模拟死锁
1package com.gjjun.concurrent; 2 3/** 4 * 模拟死锁,来源于《Java并发编程的艺术》 5 * @Author gjjun 6 * @Create 2018/8/12 7 **/ 8public class DeadLockDemo { 9 10 private static String A = "A"; 11 private static String B = "B"; 12 13 public static void main(String[] args) { 14 15 DeadLockDemo deadLockDemo = new DeadLockDemo(); 16 deadLockDemo.deadLock(); 17 } 18 19 /** 20 * 下面代码将发生死锁,原因是线程0将A资源锁定,之后线程1将B资源锁定, 21 * 之后线程1调用A资源,但是是锁定状态,所以等待A资源释放,但是A资源在2s后需要B 22 * 资源,但是B资源却等待A资源释放,所以形成了相互依赖。 23 * 24 * 可以在控制行输入命令 jps,查看类的id,之后使用jstack id查看是否发生了死锁 25 * 26 * 27 * 避免死锁的方式: 28 * 1.避免一个线程同时获取多个锁。 29 * 2.避免一个线程同时占用多个资源,尽量保证一个锁一个资源。 30 * 3.尝试使用定时锁,使用lock.tryLock(timeout)来代替使用 31 * 4.对于数据库锁,加锁和解锁必须在一个数据库连接池里。 32 */ 33 private void deadLock() { 34 Thread thread1 = new Thread(new Runnable() { 35 @Override 36 public void run() { 37 synchronized (A) { 38 try { 39 System.out.println("A"); 40 Thread.currentThread(); 41 Thread.sleep(2000); 42 } catch (InterruptedException e) { 43 e.printStackTrace(); 44 } 45 synchronized (B) { 46 System.out.println("1"); 47 } 48 } 49 } 50 }); 51 Thread thread2 = new Thread(new Runnable() { 52 @Override 53 public void run() { 54 synchronized (B) { 55 try { 56 System.out.println("B"); 57 Thread.currentThread(); 58 Thread.sleep(2000); 59 } catch (InterruptedException e) { 60 e.printStackTrace(); 61 } 62 synchronized (A) { 63 System.out.println("2"); 64 } 65 } 66 } 67 }); 68 thread1.start(); 69 thread2.start(); 70 } 71}
下面是使用jstack命令查看的死锁状态,红色框内是死锁发生的类文件及行号。
