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

ReentrantLock疑问:无线程调用时无法获锁,线程调用为何可行?

两个Condition测试程序的差异解析

这两个程序的核心差异完全在于执行锁操作和Condition等待/通知的线程归属,咱们一步步拆解清楚:

第一个程序:单线程阻塞导致逻辑卡死

先看第一个程序的核心执行流程:

public static void main(String[] args) throws InterruptedException {
 ThreadTest2 test = new ThreadTest2();
 test.conditionWait(); // 主线程直接执行此方法
 Thread.sleep(2000);
 test.conditionSignal();
}

当主线程调用conditionWait()时,它会先通过lock.lock()获取锁,打印"1",然后调用condition.await()。这里要注意:await()方法会让当前线程释放锁并进入等待状态,但问题是——conditionWait()是在主线程里执行的,await()会直接阻塞主线程,导致conditionWait()方法根本没执行完!

也就是说,主线程卡在condition.await()这一步,后面的Thread.sleep(2000)和test.conditionSignal()代码完全没有机会运行。所以程序只会打印"1",然后一直处于等待状态,永远等不到唤醒信号。

第二个程序:多线程协作实现正常等待/通知

第二个程序把等待和通知的逻辑都放到了独立的子线程中:

  • 调用conditionWait()时,会启动一个新线程A,线程A负责获取锁、打印"1"、调用await()释放锁并进入等待;
  • 主线程调用完conditionWait()后不会被阻塞,继续执行Thread.sleep(2000),随后调用conditionSignal()启动另一个新线程B;
  • 线程B此时能顺利获取锁(因为线程A已经通过await()释放了锁),打印"3",调用signal()唤醒线程A,接着打印"4",最后释放锁;
  • 线程A被唤醒后,重新获取锁,打印"2",最终释放锁。

这就是为什么第二个程序的输出是1 3 4 2——两个独立线程完成了基于Condition的标准等待/通知协作流程。

核心差异总结

  • 第一个程序:等待逻辑和后续的通知逻辑绑定在同一个主线程中,等待操作阻塞了主线程,导致通知代码永远无法执行;
  • 第二个程序:等待和通知逻辑分别在两个独立的线程中执行,等待线程释放锁后,通知线程可以正常获取锁并发送唤醒信号,完成协作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:51:23