当我们使用错误的notify()时会发生什么?

时间:2014-04-11 10:49:28

标签: java multithreading jvm

如果其他线程等待不同的条件,我们应该调用notifyAll(),这样每个其他线程都有机会获得执行。

但是我们犯了一个错误,我们假设所有线程都在等待相同的条件,我们调用notify(),让JVM选择一个线程,但是选中的线程无法运行,因为条件仍然无法满足,那么会发生什么?

所有线程都停止运行?或者JVM继续选择另一个线程来唤醒,就像notifyALL()?

一样

4 个答案:

答案 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()中删除该行国旗回归虚假。