附代码:
class Solution { // 也可写成 // private static final ReentrantLock LOCK_A = new ReentrantLock(); // private static final ReentrantLock LOCK_B = new ReentrantLock(); // 但是Lock接口是接口类型,ReentrantLock类型是实现类类型 // 如果不需要特有方法,用Lock接口即可,符合面向接口编程的原则,以后需要更换锁实现时方便 private static final Lock LOCK_A = new ReentrantLock(); private static final Lock LOCK_B = new ReentrantLock(); public void demoDeadlock() { Thread thread1 = new Thread(() -> { LOCK_A.lock(); try { System.out.println("Thread1: 持有锁 A"); // 强制让线程暂停执行(休眠),但不释放已持有的锁,确保一定死锁 Thread.sleep(100); LOCK_B.lock(); System.out.println("Thread1: 持有锁 A 和 B"); // 由于Thread.sleep()是一个可中断的方法,因此需要处理中断异常,这里打印异常和恢复中断(Thread.currentThread().interrupt())都可以,但不能抛出,因为Runnable的run()方法签名不允许抛出受检异常 } catch (InterruptedException e) { e.printStackTrace(); } finally { LOCK_B.unlock(); LOCK_A.unlock(); } }); Thread thread2 = new Thread(() -> { LOCK_B.lock(); try { System.out.println("Thread2: 持有锁 B"); // 强制让线程暂停执行(休眠),但不释放已持有的锁,确保一定死锁 Thread.sleep(100); LOCK_A.lock(); System.out.println("Thread2: 持有锁 B 和 A"); // 由于Thread.sleep()是一个可中断的方法,因此需要处理中断异常,这里打印异常和恢复中断(Thread.currentThread().interrupt())都可以,但不能抛出,因为Runnable的run()方法签名不允许抛出受检异常 } catch (InterruptedException e) { e.printStackTrace(); } finally { LOCK_A.unlock(); LOCK_B.unlock(); } }); thread1.start(); thread2.start(); } }ACM模式:
import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class Main { public static void main(String[] args) { Solution solution = new Solution(); solution.demoDeadlock(); } } class Solution { // 也可写成 // private static final ReentrantLock LOCK_A = new ReentrantLock(); // private static final ReentrantLock LOCK_B = new ReentrantLock(); // 但是Lock接口是接口类型,ReentrantLock类型是实现类类型 // 如果不需要特有方法,用Lock接口即可,符合面向接口编程的原则,以后需要更换锁实现时方便 private static final Lock LOCK_A = new ReentrantLock(); private static final Lock LOCK_B = new ReentrantLock(); public void demoDeadlock() { Thread thread1 = new Thread(() -> { LOCK_A.lock(); try { System.out.println("Thread1: 持有锁 A"); // 强制让线程暂停执行(休眠),但不释放已持有的锁,确保一定死锁 Thread.sleep(100); LOCK_B.lock(); System.out.println("Thread1: 持有锁 A 和 B"); // 由于Thread.sleep()是一个可中断的方法,因此需要处理中断异常,这里打印异常和恢复中断(Thread.currentThread().interrupt())都可以,但不能抛出,因为Runnable的run()方法签名不允许抛出受检异常 } catch (InterruptedException e) { e.printStackTrace(); } finally { LOCK_B.unlock(); LOCK_A.unlock(); } }); Thread thread2 = new Thread(() -> { LOCK_B.lock(); try { System.out.println("Thread2: 持有锁 B"); // 强制让线程暂停执行(休眠),但不释放已持有的锁,确保一定死锁 Thread.sleep(100); LOCK_A.lock(); System.out.println("Thread2: 持有锁 B 和 A"); // 由于Thread.sleep()是一个可中断的方法,因此需要处理中断异常,这里打印异常和恢复中断(Thread.currentThread().interrupt())都可以,但不能抛出,因为Runnable的run()方法签名不允许抛出受检异常 } catch (InterruptedException e) { e.printStackTrace(); } finally { LOCK_A.unlock(); LOCK_B.unlock(); } }); thread1.start(); thread2.start(); } }