如果其他线程等待不同的条件,我们应该调用notifyAll(),这样每个其他线程都有机会获得执行。
但是我们犯了一个错误,我们假设所有线程都在等待相同的条件,我们调用notify(),让JVM选择一个线程,但是选中的线程无法运行,因为条件仍然无法满足,那么会发生什么?所有线程都停止运行?或者JVM继续选择另一个线程来唤醒,就像notifyALL()?
一样答案 0 :(得分:1)
JVM无法继续选择另一个线程来唤醒,因为重新输入wait
的决定发生在更高级别的逻辑上,超出了线程调度程序"地平线&#的范围34 ;.所以是的,在您描述的场景中,所有线程都将继续等待。
答案 1 :(得分:0)
在这种情况下,你应该有一个deadlock
,因为所有的线程都会等待。
答案 2 :(得分:0)
thread a: while(a>0), thread b: while(b>0), thread c: while(c>0)
这是你的代码逻辑有缺陷。是的,它会导致deadlock
。因为你有线程将继续占用你的CPU,因为它持有锁没有其他线程可以获取它。
所有线程都停止运行?或者JVM继续选择另一个线程来唤醒,就像notifyALL()?
一样
将获得关键区域锁定的线程将进入无限循环。所有其他线程将继续等待。只要某个线程持有锁,任何JVM都不会通知其他线程。
答案 3 :(得分:0)
对于同一个监视器,wait()的所有线程都应该在循环中等待相同的条件变为true。通知()监视器的线程只应在使条件为真后才这样做。如果您遵循这些规则,那么至少会有一个线程被唤醒并且能够取得进展。
E.g;
final Object lock = new Object();
final AtomicBoolean timeToGo = new AtomicBoolean(false);
Runnable waiter = new Runnable() {
public void run() {
synchronized(lock) {
while (! timeToGo.get()) {
lock.wait();
}
System.out.println("Hello!");
timeToGo.set(false);
}
}
};
Runnable notifier = new Runnable() {
public void run() {
synchronized(lock) {
timeToGo.set(true);
lock.notify();
}
}
};
如果在waiter.run()的wait()方法中挂起了五个线程,并且一个线程调用了notifier.run(),那么五个线程中只有一个会打印“Hello!”并退出。其他人将继续等待下一个notifier.run()调用。
如果你想要在调用notifier.run()时打印hello所有线程,则将lock.notify()调用更改为lock.notifyAll(),并从设置的waiter.run()中删除该行国旗回归虚假。