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

为何Java中Thread.holdsLock()在持有锁时会返回false?

问题根因与解决方案

核心问题出在**Thread.holdsLock()根本不认识ReentrantLock这种显式锁**,它只能检测Java的内置监视器锁(也就是synchronized关键字获取的锁)。

具体分析

  1. Thread.holdsLock(Object obj)的设计目标是判断当前线程是否持有指定对象的内置锁——也就是当你用synchronized(obj)或者进入synchronized方法时获得的锁。它和ReentrantLock这类通过API实现的显式锁完全不兼容,所以用它判断ReentrantLock的持有状态从一开始就是错误的。
  2. 你的代码里,当线程在lockInterruptibly()调用过程中被中断,此时线程还没拿到锁就进入catch块,Thread.holdsLock()返回false是正常的;但如果线程已经成功获取了ReentrantLock,Thread.holdsLock()同样会返回false,导致finally块里不执行unlock(),锁会被永久持有。
  3. 直接去掉if判断时,未持有锁的线程调用unlock()会抛出IllegalMonitorStateException,这是ReentrantLock的正常行为——只有持有锁的线程才能解锁。

正确的写法

用ReentrantLock自带的isHeldByCurrentThread()方法来判断当前线程是否持有该锁,这是专门为显式锁设计的API:

// setup
while(!exitCondition)
  try {
    myLock.lockInterruptibly();
    // do stuff
    if(exitCondition) tellMain(); // this causes main to interrupt all threads
    // sleep for a bit
  } catch (InterruptedException e) {
    // clean up
    break;
  } finally {
     if(myLock.isHeldByCurrentThread()) {
         myLock.unlock();
     }
  }
}
// termination message

额外说明

如果需要更精细的控制,ReentrantLock还提供了getHoldCount()方法,返回当前线程持有该锁的次数(你的场景里是0或1),用getHoldCount() > 0也能达到同样的判断效果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 15:47:48