我正在练习readers and writers problem,并提出以下解决方案。但是,该程序在打印出以下结果后会自行阻止。
$ Read content: planets
我的想法是first solution的修改版本。使用2个信号量,一个称为 readMutex 的信号量确保一次只能读取一个线程来更新 numOfReaders ,而另一个信号量的 accessToResource 确保该时间点是读者正在阅读内容,作者应该等待。这是我的代码。
import java.util.concurrent.Semaphore;
public class ReadersAndWriters {
public static final Semaphore accessToResource = new Semaphore(1, true);
public static final Semaphore readMutex = new Semaphore(1, true);
public static String content = "planets";
public static int numOfReaders;
static class Reader extends Thread {
void read() {
try {
readMutex.acquire();
numOfReaders++;
if (numOfReaders == 1) {
accessToResource.acquire();
}
readMutex.release();
// read content, not a critical section
System.out.println("Read content:\t" + content);
readMutex.acquire();
numOfReaders--;
if (numOfReaders <= 0) {
accessToResource.release();
}
readMutex.release();
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
public void run() {
read();
}
}
static class Writer extends Thread {
String text;
Writer(String text) {
this.text = text;
}
void write() {
try {
readMutex.acquire();
accessToResource.acquire();
// critical section
content = text;
System.out.println("Content changed:\t" + content);
// end of critical section
accessToResource.release();
readMutex.release();
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
public void run() {
write();
}
}
public static void main(String[] args) {
Reader t1 = new Reader();
Reader t2 = new Reader();
Writer t3 = new Writer("stars");
Reader t4 = new Reader();
Writer t5 = new Writer("restaurant at the end of universe");
Reader t6 = new Reader();
Reader t7 = new Reader();
t1.start();
t2.start();
t3.start();
t4.start();
t5.start();
t6.start();
t7.start();
}
}
答案 0 :(得分:3)
当一个Reader
获得了accessToResource
并尝试获得readMutex
时:
if (numOfReaders == 1) {
accessToResource.acquire();
}
readMutex.release();
System.out.println("Read content:\t" + content);
readMutex.acquire(); // -------> here
另一个Writter
已获得readMutex
并尝试获得accessToResource
:
readMutex.acquire();
accessToResource.acquire(); // ------> here
发生死锁。
由于accessToResource
和readMutex
的许可是1
,因此Reader
和Writter
都无法前进。