代码 通过本类的static属性来设置锁 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 import java.lang.Runnable; public class DeadLock implements Runnable { private int value; private static byte [] o1 = new byte [0 ], o2 = new byte [0 ]; public DeadLock (int value) { this .value = value; } public void run () { if (value == 1 ) { synchronized (o1) { try { Thread.sleep(3000 ); for (int i = 0 ; i < 10 ; i ++) { System.out.println("o1->" + i); } } catch (InterruptedException e) { e.printStackTrace(); } synchronized (o2) { System.out.println("o2, value = " + value); } } } if (value == 2 ) { synchronized (o2) { try { Thread.sleep(3000 ); for (int i = 10 ; i < 20 ; i ++) { System.out.println("o2->" + i); } } catch (InterruptedException e) { e.printStackTrace(); } synchronized (o1) { System.out.println("o1, value = " + value); } } } } public static void main (String[] args) { DeadLock d1 = new DeadLock (1 ); DeadLock d2 = new DeadLock (2 ); new Thread (d1).start(); new Thread (d2).start(); } }
通过独立的类的static属性来设置锁 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 class Lock { public static Lock locka = new Lock (); public static Lock lockb = new Lock (); }public class DeadLockThread extends Thread { boolean flag; DeadLockThread(boolean flag) { this .flag = flag; } @Override public void run () { if (flag) { while (true ) { synchronized (Lock.locka) { System.out.println(Thread.currentThread().getName() + "...if locka" ); synchronized (Lock.lockb) { System.out.println(Thread.currentThread().getName() + "...else lockb" ); } } } } else { while (true ) { synchronized (Lock.lockb) { System.out.println(Thread.currentThread().getName() + "...if lockb" ); synchronized (Lock.locka) { System.out.println(Thread.currentThread().getName() + "...else lockb" ); } } } } } public static void main (String[] args) { DeadLockThread t1 = new DeadLockThread (false ); DeadLockThread t2 = new DeadLockThread (true ); t1.start(); t2.start(); } }
总结 导致死锁的根源 不适当地运用“synchronized”关键词来管理线程对特定对象的访问。
“synchronized”关键词的作用是,确保在某个时刻只有一个线程被允许执行特定的代码块,因此,被允许执行的线程首先必须拥有对变量或对象的排他性的访问权。当线程访问对象时,线程会给对象加锁,而这个锁导致其它也想访问同一对象的线程被阻塞,直至第一个线程释放它加在对象上的锁。
排查死锁的工具 Windows下可以用可视化图形界面jconsole (Linux下也有这个命令,只是我们一般服务器不装图形界面,因此不用这个)
Linux下一般先通过jps查找到java进程ID,然后通过jstack打印栈信息,如果存在死锁,栈信息里面会注明的,类似这样:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 Found one Java-level deadlock: ============================="Thread-1" : waiting to lock monitor 0x0000000054d7c618 (object 0x00000000eac13ab0 , a [B), which is held by "Thread-0" "Thread-0" : waiting to lock monitor 0x0000000054d7e9d8 (object 0x00000000eac13ac0 , a [B), which is held by "Thread-1" Java stack information for the threads listed above: ==================================================="Thread-1" : at DeadLock.run(DeadLock.java:60) - waiting to lock <0x00000000eac13ab0 > (a [B) - locked <0x00000000eac13ac0 > (a [B) at java.lang.Thread.run(Unknown Source)"Thread-0" : at DeadLock.run(DeadLock.java:40) - waiting to lock <0x00000000eac13ac0 > (a [B) - locked <0x00000000eac13ab0 > (a [B) at java.lang.Thread.run(Unknown Source) Found 1 deadlock.