You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java中调用notifyAll后,为何两个等待线程都能完成执行?

解答你的wait/notifyAll线程通信疑问

嘿,这个问题问到点子上了!很多刚接触Java线程通信的开发者都会在这里绕晕,我来给你掰扯清楚:

核心逻辑:notifyAll不是让线程“同时执行”,而是让它们“依次竞争锁”

你之前的理解没错——同一时间只有一个线程能拿到对象锁,但notifyAll的作用是把所有在该锁上等待的线程都唤醒,让它们进入锁的竞争队列,而不是只唤醒一个。

举个对应你场景的例子:

  1. 主线程调用lock.notifyAll()后,t1和t2都从wait状态被唤醒,变成可运行状态,开始竞争lock对象的锁。
  2. 假设t1先抢到锁,进入同步块执行代码,输出你看到的:synchronized block have finished,执行完后释放lock锁。
  3. 这时候t2就有机会抢到刚释放的锁,进入自己的同步块执行代码,同样输出那句话,执行完释放锁。
    所以两个线程最终都能完成执行,只是有先后顺序而已。

为什么用notify()时程序会卡着?

notify()和notifyAll的区别就在这里:notify只会随机唤醒一个在该锁上等待的线程,另一个线程还留在等待队列里,没人去唤醒它。
比如你用notify()时,可能只唤醒了t1,t2还在wait状态;或者只唤醒了t2,t1还在等。这个没被唤醒的线程会一直处于等待状态,而JVM必须等所有非守护线程结束才会退出,所以你的程序就永远停着,不会结束。

再补个关键细节

被notify/notifyAll唤醒的线程,不是直接继续执行wait之后的代码,而是必须重新获取对象锁,只有拿到锁才能继续往下走。这就是为什么即使notifyAll唤醒了所有线程,它们也不会同时执行,而是排队抢锁依次执行。

内容的提问来源于stack exchange,提问作者Nicky

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 09:12:28