此代码片段显示了 Java 中死锁的示例,强制 Thread1 获取 resource1 上的 lock1,并强制 Thread2 获取 resource2 上的 lock2。然后 Thread1 尝试获取 lock2,而 Thread2 尝试获取 lock1。这会导致死锁。
我本以为根据 this 看到 Thread2 和 Thread1 状态为 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();
}
}
}
您引用的文档是关于内在锁的 - 内置于每个 Java 对象(也称为监视器)中的锁。它们是一个低级别的、稍微遗留的机制,具有已知的警告。内在锁与
synchronized
关键字一起使用,并且仅当线程进入静态标记为 synchronized
的代码块时才被获取。
您正在使用不同的、更高级别的 API,因此无论文档中关于锁的内容如何,都不适用。我从未研究过
ReentrantLock
的实现,但是 - 正如您从 Thread
的状态中看到的 - 它不是使用 synchronized
块来停放线程,而是调用 Object
' s wait
方法(始终由 synchronized
块内部构成,并形成 Java 线程构建的另一个低级原语)。