当前位置: 首页 > 知识库问答 >
问题:

2个线程如何才能在NotifyAll之后获得锁?

通啸
2023-03-14

有2个线程和1个主线程。主线程做notifyall。它唤醒剩下的2个线程,两个线程都打印

":syncronized block have finished"

但是我读到过,如果有2个线程在等待锁,那么notifyAll将唤醒每个线程,但是锁将只被1个线程获取。

所以我的问题是为什么t1和t2线程都在完成它们的执行?

共有1个答案

阎修杰
2023-03-14

问题的答案隐藏在notify()和notifyAll()方法的文档中。

在您的特殊情况下,lock对象的所有者即两个线程正在同步的对象是主线程。当我们调用lock对象上的notify()方法时,如果看到文档,它会说“只有单线程”被唤醒。因此,您看到了为什么程序会挂起第二个线程从来没有被“Notified”唤醒。第一个将锁释放到“等待”状态的线程实际上是被唤醒的线程。

如果您看到“NotifyAll()”的文档,它声明“唤醒在该对象监视器上等待的所有线程。线程通过调用wait方法之一在对象监视器上等待。”强调“all”意味着已经获得锁的线程和等待“通知”的线程都被唤醒。

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多线程的新手。我已经进行了一些研究,阅读了教程并进行了测试,但是我仍然遇到这个问题。基本上,我正在设置游戏的骨架,我想拥有一个主要的活动类,一个包含方法的线程类,执行各种慢速操作(读取文件并将内容解压缩到缓冲区),并具有一个线程是游戏循环对UI操作的反应。 首先,我有main活动类,该类实例化并启动一个单独的线程: 然后,我有了实现游戏逻辑线程的类: 最后,线程类(其中包含

  • 1如题,我知道wait,notify,notifyAll一定要在同步代码块中使用。但我有几个问题: 1.如下,我使用ReentrantLock作为锁,为什么会报错? 然后通过Thread类运行run,为什么会提示关于java.lang.IllegalMonitorStateException错误? 2.我使用Task类里的一个静态字符串变量,比如static String mylock="mylo

  • 问题内容: 在下面的代码中,我按预期在100秒后捕获了TimeoutException。在这一点上,我希望代码从main退出,而程序终止,但它会一直打印到控制台。如何使任务在超时后停止执行? 问题答案: 您需要在超时时取消任务(并中断其线程)。那就是方法。:

  • 问题内容: 我想要一个布尔值来通知系统的某些部分特定服务已启动。 由于某些奇怪的原因,我得到了错误。 奇怪的是notifyAll()在一个同步块内,该块控制着我调用notifyAll()的对象。 我的课是这样开始的: 我正在开发一个android应用程序。我认为它不会影响任何事情,但是我会在注释中补充这个问题,以防影响Java的工作方式。 如果对象锁定在同步块中,为什么会出现异常? 问题答案: 线

  • 问题内容: 我有很多代码, 调用时处理器很小,有时会导致性能问题(100毫秒),因此我想知道当前等待对象释放的线程是什么。 我想在调用之前打印所有等待对象释放的线程 问题答案: 是否所有线程都在资源上等待相同的条件?如果是,则可以尝试替换,尽管实际上不建议这样做。AFAIK,无法“检索”在给定对象上等待的所有线程的列表(尽管您可以通过编程方式获取进程的线程转储并查看线程,但是我敢肯定那不是您拥有的

  • 若要恢复挂起在给定对象上的线程,其他一些线程必须在引用相同对象的同步语句或方法中执行预先定义的方法notify。和wait一样,notify也没有参数。作为对notify调用的响应,语言运行时系统选择挂起在对象上的任意线程并使其可运行。如果没有这样的线程,那么通知是一个无操作。就像在Mesa中一样,有时唤醒在给定对象中等待的所有线程可能是合适的;Java为此提供了一个内置的notifyAll方法。

  • 我有组表,它有列id,名称,时间戳。当有一个组的更新时,时间戳也被更新为Current。 我正在尝试使用查询显示两个ID之间的组计数。 group表具有: 任何帮助都是非常感谢的。

  • 我正在编写一个基于await/sleep范式的网络绑定应用程序。 我更喜欢这样一个答案,不创建任何额外的线程