为何Java中Thread.holdsLock()在持有锁时会返回false?
问题根因与解决方案
核心问题出在**Thread.holdsLock()根本不认识ReentrantLock这种显式锁**,它只能检测Java的内置监视器锁(也就是synchronized关键字获取的锁)。
具体分析
Thread.holdsLock(Object obj)的设计目标是判断当前线程是否持有指定对象的内置锁——也就是当你用synchronized(obj)或者进入synchronized方法时获得的锁。它和ReentrantLock这类通过API实现的显式锁完全不兼容,所以用它判断ReentrantLock的持有状态从一开始就是错误的。- 你的代码里,当线程在
lockInterruptibly()调用过程中被中断,此时线程还没拿到锁就进入catch块,Thread.holdsLock()返回false是正常的;但如果线程已经成功获取了ReentrantLock,Thread.holdsLock()同样会返回false,导致finally块里不执行unlock(),锁会被永久持有。 - 直接去掉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
相关产品推荐
相关产品推荐

