Java中ReentrantLock死锁:线程状态为何是WAITING而非BLOCKED?
问题
通过让Thread1获取resource1的lock1、Thread2获取resource2的lock2,再分别尝试获取对方持有的锁,制造了Java死锁场景。根据Java官方文档,预期Thread1和Thread2的状态为BLOCKED,但通过thread.getState()监控发现线程一直处于WAITING状态,恳请帮忙解释原因。
锁在主类中的声明:
Lock lock1 = new ReentrantLock(); Lock lock2 = new ReentrantLock();
ThreadClass的代码如下:
import java.util.concurrent.locks.Lock; public class ThreadClass extends Thread { private Lock lock1; private Lock lock2; private Resource resource1; private Resource resource2; public ThreadClass(Resource resource1, Resource resource2, String name, Lock lock1, Lock lock2) { this.resource1 = resource1; this.resource2 = resource2; this.lock1 = lock1; this.lock2 = lock2; this.setName(name); } @Override public void run() { if (Thread.currentThread().getName().equals("Thread1")) { lock1.lock(); System.out.println(Thread.currentThread().getName() + ": Using " + resource1.name); // Simulating work on RESOURCE 1 lock2.lock(); System.out.println(Thread.currentThread().getName() + ": Using " + resource2.name); // Simulating work on RESOURCE 2 lock2.unlock(); lock1.unlock(); } if (Thread.currentThread().getName().equals("Thread2")) { lock2.lock(); // Simulating work on RESOURCE 2 lock1.lock(); System.out.println(Thread.currentThread().getName() + ": Using resource1"); lock1.unlock(); lock2.unlock(); } } }
原因解释
- BLOCKED状态的适用范围:
BLOCKED状态仅针对Java的内置锁(synchronized关键字)。当线程竞争对象的监视器锁失败时,才会进入BLOCKED状态。 - ReentrantLock的锁等待机制:你使用的
ReentrantLock属于JUC(java.util.concurrent)包下的显式锁,它基于AQS(抽象队列同步器)实现。当线程调用lock()方法获取锁失败时,会被加入到AQS的等待队列中,随后通过LockSupport.park()方法挂起线程,此时线程的状态就会变为WAITING(如果使用带超时的lock()方法则是TIMED_WAITING)。 - 死锁场景下的状态差异:用
synchronized制造死锁时,线程会因竞争内置锁而处于BLOCKED状态;而用ReentrantLock的lock()制造死锁时,线程因AQS的挂起机制进入WAITING状态,这是两种锁实现机制不同导致的正常现象。
内容的提问来源于stack exchange,提问作者gaetano
相关产品推荐
相关产品推荐

