我正在阅读有关 Java 中使用 wait/notify/notifyAll 的线程间通信的内容。
我浏览了这个答案:https://stackoverflow.com/a/36276832
有 2 个线程和 1 个主线程。主线程执行notifyAll
。它唤醒剩余的 2 个线程,并且两个线程都打印
":syncronized block have finished"
但我读到,如果有 2 个线程正在等待锁,notifyAll 将唤醒每个线程,但只有 1 个线程会获取锁。
所以我的问题是 t1 和 t2 线程如何完成执行?
当我从 lock.notifyAll();
更改为 lock.notify();
时,Java 程序永远不会结束。
t1/t2 中的一个线程将处于等待状态。
有人可以回答一下吗?如果不清楚的话我可以进一步解释我的疑问。
简单来说问题:如果2个线程正在等待同一个锁,而第3个线程执行notifyAll,则只有其中一个线程获得锁,另一个线程仍处于等待状态,因此在上述情况下,为什么两个线程都能完成执行呢?
最佳答案
您的问题的答案隐藏在 notify() 的文档中和 notifyAll()方法。
在您的特定情况下,两个线程正在同步的锁对象的所有者是主线程。当我们在锁对象上调用notify()方法时,如果您看到文档,它会说“仅单个线程”被唤醒。因此您就会明白为什么程序会挂起第二个线程永远不会“通知”被唤醒。第一个在进入“等待”状态时释放锁的线程实际上是被唤醒的线程。
如果您看到“notifyAll()”的文档,它指出“唤醒正在等待此对象监视器的所有线程。线程通过调用其中一个等待方法来等待对象的监视器”。强调“全部”意味着你的已经获得锁并等待“通知”的线程都被唤醒。
下面是当我们将调用从notifyAll()更改为notify()时的结果,在这种情况下,第一个执行等待的线程被通知。
Time: Tue Jul 09 12:42:37 CDT 2019;Thread-1:thread goes into waiting state and releases the lock
Time: Tue Jul 09 12:42:37 CDT 2019;Thread-0:only one thread can be in synchronized block
Time: Tue Jul 09 12:42:42 CDT 2019;Thread-0:thread goes into waiting state and releases the lock
Time: Tue Jul 09 12:42:47 CDT 2019;Notifying all
Time: Tue Jul 09 12:42:47 CDT 2019;Thread-1:thread is awake and have reacquired the lock
Time: Tue Jul 09 12:42:47 CDT 2019;Thread-1:syncronized block have finished
关于java - 2个线程如何在notifyAll之后获得锁?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56949817/