Java中wait(long timeout)超时后线程未唤醒问题求助
问题原因分析
核心在于Java中wait(long timeout)的唤醒与后续执行是两个独立阶段:
- 超时时间到达后,线程会从等待队列被唤醒,进入锁竞争队列
- 只有成功获取到对象锁,线程才能真正继续执行后续代码
你的测试场景里:
- Thread-1调用
lock.wait(5_000)时,会先释放lock对象的锁,进入等待状态 - Thread-2持有
lock的锁并调用Thread.sleep(10_000),sleep期间不会释放锁 - 5秒后Thread-1确实被唤醒,但此时
lock的锁仍被Thread-2占用,Thread-1只能进入锁的阻塞队列等待获取锁 - 直到10秒后Thread-2的sleep结束、释放锁(退出同步块时),Thread-1才能拿到锁继续执行——所以你看起来像是“wait超时没生效”
后续的两种正常情况也能印证这个逻辑:
- 把wait时长改成20秒:Thread-2的sleep先结束并释放锁,Thread-1超时唤醒后能直接拿到锁,执行正常
- 移除Thread-2:没有其他线程持有锁,Thread-1超时唤醒后可立刻获取锁继续执行,功能正常
补充验证建议
可以在代码中添加日志验证这个过程:
- 在Thread-1的
wait调用前、唤醒后分别打印日志 - 在Thread-2的
sleep前后打印日志
你会发现Thread-1的“唤醒日志”在5秒时就会输出,但后续执行日志要等到Thread-2释放锁后才会出现
内容的提问来源于stack exchange,提问作者flyingfox
相关产品推荐
相关产品推荐

