我的线程没有得到通知,我的程序挂起
问题描述:
以下代码没有通知线程读取器执行写入器,然后终止。这是为什么? notifyall
应唤醒处于等待状态的所有线程。我的线程没有得到通知,我的程序挂起
public class Testing {
public static void main(String[] args) {
Testing testing=new Testing();
testing.reader.start();
testing.writer.start();
}
Thread reader = new Thread("reader") {
public void run() {
System.out.println("reader started");
synchronized (this) {
try {
wait();
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
for (int i = 0; i < 10; i++) {
System.out.println("reader " + i);
}
}
};
Thread writer = new Thread("writer") {
public void run() {
System.out.println("writer started");
for (int i = 0; i < 10; i++) {
System.out.println("writer " + i);
}
synchronized (Thread.currentThread()) {
notifyAll();
}
}
};
}
答
以下代码没有通知线程阅读器执行编写器,然后终止。这是为什么?
您的程序没有完成,因为写入程序线程终止,但读卡器线程卡在wait()
中。您的代码的问题在于,读者线程正在等待它自己的线程对象,而写入者线程正在通知它自己的线程对象,这是不同的。你需要做的是让他们每个人等待并通知相同的对象实例。
速战速决是使用静态锁定对象:
private static final Object lockObject = new Object();
// reader:
synchronized (lockObject) {
lockObject.wait();
...
// writer
synchronized (lockObject) {
lockObject.notify();
那么无论是读者和作家被锁定,等待,并通知-ING在同一最终对象实例。在无法更改的字段上同步是一种很好的模式,因此private final Object
或某些最好。此外,你只有一个线程,所以notify()
就足够了。
但是,您的代码仍然存在竞争条件问题。您的作者可能(尽管不太可能)在之前致电notifyAll()
,读者可以访问wait()
。如果通知发生并且没有人在等待,那么它是一个noop,读者在到达wait()
时会挂起。
一个更好的解决办法是使用共享AtomicBoolean
:
private final AtomicBoolean writerDone = new AtomicBoolean();
...
// reader
while (!writerDone.get()) {
synchronized (writerDone) {
writerDone.wait();
}
}
// writer
writerDone.set(true);
synchronized (writerDone) {
writerDone.notifyAll();
}
答
你只是做变化不大,如下:
public static void threadTest(){
Test testing = new Test();
testing.lock = new Object();
testing.reader.start();
testing.writer.start();
}
private Object lock;
Thread reader = new Thread("reader") {
public void run() {
System.out.println("reader started");
synchronized (lock) {
try {
lock.wait();
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
for (int i = 0; i < 10; i++) {
System.out.println("reader " + i);
}
}
};
Thread writer = new Thread("writer") {
public void run() {
System.out.println("writer started");
for (int i = 0; i < 10; i++) {
System.out.println("writer " + i);
}
synchronized (lock) {
lock.notifyAll();
}
}
};
+0
感谢帮助。 :) –
是返回读线程同时呼吁当前thread.But既不notify和notifyall不会唤醒等待的线程。 –
哎呀!那是一个错误。我会将其改正为作家。事实上,当前返回的线索是作家。您可以帮助我了解如何通知读者线索。 –
如果没有先确认,在'synchronized'块中,不要等待的东西没有发生,就不要调用'wait'。在调用wait后不要确认你正在等待的东西已经发生。 (另外,你的作者调用'notifyAll'而不改变'synchronized'块中的任何内容,所以没有什么可以通知的。) –