【发布时间】:2020-12-07 00:46:32
【问题描述】:
在这里,我们用 Java 构建了一个并发程序,在该程序中我们模拟了一个我们从中读取和写入的数据库。我们有 20 个同时阅读的读者和 2 个不同时阅读的作者。
读者开始阅读,读完后,作家开始写作,这导致作家挨饿。
我得到的输出:
Reader 15 started reading
Reader 5 started reading
Reader 2 started reading
Reader 7 started reading
Reader 15 finished reading
Reader 5 finished reading
Reader 16 started reading
...
...
Writer 21 started writing
Writer 21 finished writing
Writer 20 started writing
Writer 20 finished writing
所以,我一直在尝试对该程序实施 FIFO 顺序,以消除这种饥饿。例如,输出应该是 R1, W1, R2, R3, R4, W2 (R -- reader, W-- writer)。我被困在这一点上,我不知道是否改变我的算法。提前致谢!
import java.util.concurrent.ThreadLocalRandom;
public class Runner {
public static void main(String[] args) {
try {
runDB(20, 2, new BetterDB());
} catch (InterruptedException ignored){}
}
static void runDB(int readersAmount, int writersAmount, DB database) throws InterruptedException {
assert readersAmount > 0;
assert writersAmount > 0;
Thread[] threads = new Thread[readersAmount + writersAmount];
for (int i = 0; i < readersAmount; i++){
threads[i] = new Thread(new Reader(database, i));
}
for (int i = readersAmount; i < readersAmount + writersAmount; i++){
threads[i] = new Thread(new Writer(database, i));
}
for (Thread thread : threads){
thread.start();
}
for (Thread thread : threads){
thread.join();
}
}
}
interface DB {
void read(int readerID) throws InterruptedException;
void write(int writerId);
}
class BetterDB implements DB {
long READ_TIME = 500; // milliseconds
long WRITE_TIME = 1000; // milliseconds
int readers = 0;
@Override
public void read(int readerID) throws InterruptedException {
synchronized (this) {
readers++;
System.out.printf("Reader %d started reading\n", readerID);
}
try {
ThreadLocalRandom random = ThreadLocalRandom.current();
Thread.sleep(random.nextLong(READ_TIME));
} catch (InterruptedException ignored) {}
synchronized (this) {
readers--;
System.out.printf("Reader %d finished reading\n", readerID);
if (readers == 0) {
this.notifyAll();
}
}
}
@Override
public synchronized void write(int writerId) {
try{
while(readers > 0){
this.wait();
}
} catch (InterruptedException ignored) {}
System.out.printf("Writer %d started writing\n", writerId);
try{
ThreadLocalRandom random = ThreadLocalRandom.current();
Thread.sleep(random.nextLong(WRITE_TIME));
} catch (InterruptedException ignored) {}
System.out.printf("Writer %d finished writing\n", writerId);
}
}
class Reader implements Runnable {
final long READER_DELAY = 500; // milliseconds
private final DB database;
private int id;
Reader(DB database, int id){
this.database = database;
this.id = id;
}
@Override
public void run() {
try{
ThreadLocalRandom random = ThreadLocalRandom.current();
Thread.sleep(random.nextLong(READER_DELAY));
database.read(id);
} catch (InterruptedException ignored) {}
}
}
class Writer implements Runnable {
final long WRITER_DELAY = 400; // milliseconds
private final DB database;
private int id;
Writer(DB database, int id){
this.database = database;
this.id = id;
}
@Override
public void run() {
try{
ThreadLocalRandom random = ThreadLocalRandom.current();
Thread.sleep(random.nextLong(WRITER_DELAY));
database.write(id);
} catch (InterruptedException ignored) {}
}
}
【问题讨论】:
-
所以你想让一些写入和读取混合?
标签: java multithreading concurrency fifo