java - 2个线程如何在notifyAll之后获得锁?

标签 java multithreading wait synchronized

我正在阅读有关 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/

相关文章:

java - Viewholder的getAdapterPosition和getLayoutPosition始终为-1

c - 如果在这段代码中直接将变量 i 传递给线程会发生什么?

停止和等待算法的 Python 实现

java - 如何为给定路径创建文件(包括文件夹)?

java - 如何通过 Selenium Java 使用动态 xpath 将鼠标悬停在不同图像上

ios - NSOperationQueue : Trouble understanding the order

multithreading - Delphi线程锁等待字符串操作

java - 让线程等待对话框输入

java - 无法从浏览器读取 Cookie

c - pthread_join 似乎修改了我的循环索引