Ваш код является хорошим примером мертвой блокировки, поскольку ReenttrantLock - это блокировка взаимного исключения с тем же поведением, что и неявная блокировка доступа к монитору с использованием синхронизированного.Однако вы не видите тупик из-за этой части:
private void execute() {
new Thread(this::processThis).start();
new Thread(this::processThat).start();
}
После создания и запуска первого потока создание второго потока займет некоторое время.Для создания новой нити JVM требуется около 50, а может и меньше, звучит очень коротко, но этого достаточно, чтобы завершить первую нить, и, следовательно, не будет мертвой блокировки.
Я добавил Thread.sleep();
в ваш код, чтобы оба потока могли выполняться как-то параллельно.
package com.company;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class DeadlockBasics {
private Lock lockA = new ReentrantLock();
private Lock lockB = new ReentrantLock();
public static void main(String[] args) {
DeadlockBasics dk = new DeadlockBasics();
dk.execute();
}
private void execute() {
new Thread(this::processThis).start();
new Thread(this::processThat).start();
}
// called by thread 1
private void processThis() {
lockA.lock();
// process resource A
try {
Thread.sleep(1000); //Wait for thread 2 to be executed
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread 1 will own lock a");
lockB.lock();
// process resource B
System.out.println("Thread 1 will own lock b");
lockA.unlock();
lockB.unlock();
// Both locks will now released from thread 1
}
// called by thread 2
private void processThat() {
lockB.lock();
// process resource B
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread 2 will own lock b");
lockA.lock();
// process resource A
System.out.println("Thread 2 will own lock a");
lockA.unlock();
lockB.unlock();
// Both locks are released by thread 2
}
}