如果其他线程等待不同的条件,我们应该调用notifyAll(),这样每个其他线程都有机会获得执行。但是我们犯了一个错误,我们假设所有线程都在等待相同的条件,我们调用notify(),让JVM选择一个线程,但是选中的线程不能运行,因为条件仍然不能满足,那么会发生什么?当我们使用错误的notify()时会发生什么?
所有线程都停止运行?或者JVM继续选择另一个线程来唤醒,就像notifyALL()一样?
如果其他线程等待不同的条件,我们应该调用notifyAll(),这样每个其他线程都有机会获得执行。但是我们犯了一个错误,我们假设所有线程都在等待相同的条件,我们调用notify(),让JVM选择一个线程,但是选中的线程不能运行,因为条件仍然不能满足,那么会发生什么?当我们使用错误的notify()时会发生什么?
所有线程都停止运行?或者JVM继续选择另一个线程来唤醒,就像notifyALL()一样?
JVM不能继续选择另一个线程来唤醒,因为重新输入wait
的决定发生在更高级别的逻辑上,超出了线程调度程序的“时域”范围。所以是的,在你描述的场景中,所有的线程都会继续等待。
在这种情况下,您应该有一个deadlock
,因为所有的线程都会停滞不前。
thread a: while(a>0), thread b: while(b>0), thread c: while(c>0)
这是您的代码逻辑有缺陷。是的,这将导致deadlock
。既然你有线程将继续吃掉你的CPU,并且因为它拥有锁定,所以其他线程无法获取它。
所有线程都停止运行?或者JVM继续选择另一个线程来唤醒,就像notifyALL()一样?
将获得关键区域锁定的线程将进入无限循环。所有其他线程将继续等待。只要某个线程持有该锁,任何JVM都不会通知其他线程。
所有等待同一监视器的线程都应等待循环中的相同条件成为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()中删除该行,即将标志设置为false。
'但选中的线程无法运行,因为条件仍然不能满足请详细说明? –
线程a:while(a> 0),线程b:while(b> 0),线程c:while(c> 0)... – lovespring
'notify'唤醒已在该对象上调用wait的线程。这里没有什么可以满足的。 –