今天面试有一道题,写一个死锁的程序,自己也是短路了,没写出来,回来写下。
死锁常见的情况是A线程持有a锁、阻塞于b锁,B线程持有b锁,阻塞于a锁,形成一个循环阻塞的状态。
import java.util.concurrent.TimeUnit;public class CyclicLock { private static Object o1 = new Object(); private static Object o2 = new Object(); public static void main(String[] args) { new Thread(new Runnable() { @Override public void run() { synchronized(o1) { try { TimeUnit.SECONDS.sleep(5); } catch (InterruptedException e) { e.printStackTrace(); } synchronized(o2) { } } } }).start(); new Thread(new Runnable() { @Override public void run() { synchronized(o2) { try { TimeUnit.SECONDS.sleep(5); } catch (InterruptedException e) { e.printStackTrace(); } synchronized(o1) { } } } }).start(); }}
用了下Java栈跟踪工具jstack,可以生成当前虚拟机中的线程快照,此文件称为thread dump。(而用jmap -dump生成的是堆转储快照,heap dump)
这里居然还自动检测出死锁,略牛略牛。
C:\Users\Administrator>jps11168 CyclicLock350410204 JpsC:\Users\Administrator>C:\Users\Administrator>jstack -l 111682017-03-22 23:24:24Full thread dump Java HotSpot(TM) Client VM (25.121-b13 mixed mode, sharing):"DestroyJavaVM" #10 prio=5 os_prio=0 tid=0x001ac800 nid=0x20f0 waiting on condition [0x00000000] java.lang.Thread.State: RUNNABLE Locked ownable synchronizers: - None"Thread-1" #9 prio=5 os_prio=0 tid=0x00a1f400 nid=0x2a28 waiting for monitor entry [0x15f2f000] java.lang.Thread.State: BLOCKED (on object monitor) at CyclicLock$2.run(CyclicLock.java:37) - waiting to lock <0x044ab368> (a java.lang.Object) - locked <0x044ab370> (a java.lang.Object) at java.lang.Thread.run(Unknown Source) Locked ownable synchronizers: - None"Thread-0" #8 prio=5 os_prio=0 tid=0x00a1e400 nid=0x2bf0 waiting for monitor entry [0x15bff000] java.lang.Thread.State: BLOCKED (on object monitor) at CyclicLock$1.run(CyclicLock.java:20) - waiting to lock <0x044ab370> (a java.lang.Object) - locked <0x044ab368> (a java.lang.Object) at java.lang.Thread.run(Unknown Source) Locked ownable synchronizers: - None"Service Thread" #7 daemon prio=9 os_prio=0 tid=0x009e6c00 nid=0x2698 runnable [0x00000000] java.lang.Thread.State: RUNNABLE Locked ownable synchronizers: - None"C1 CompilerThread0" #6 daemon prio=9 os_prio=2 tid=0x009dfc00 nid=0x2278 waiting on condition [0x00000000] java.lang.Thread.State: RUNNABLE Locked ownable synchronizers: - None"Attach Listener" #5 daemon prio=5 os_prio=2 tid=0x009de800 nid=0x27d8 waiting on condition [0x00000000] java.lang.Thread.State: RUNNABLE Locked ownable synchronizers: - None"Signal Dispatcher" #4 daemon prio=9 os_prio=2 tid=0x009db400 nid=0x52c runnable [0x00000000] java.lang.Thread.State: RUNNABLE Locked ownable synchronizers: - None"Finalizer" #3 daemon prio=8 os_prio=1 tid=0x009c0c00 nid=0x2214 in Object.wait() [0x156bf000] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on <0x04408978> (a java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(Unknown Source) - locked <0x04408978> (a java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(Unknown Source) at java.lang.ref.Finalizer$FinalizerThread.run(Unknown Source) Locked ownable synchronizers: - None"Reference Handler" #2 daemon prio=10 os_prio=2 tid=0x00965000 nid=0x2624 in Object.wait() [0x155ff000] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on <0x04406a90> (a java.lang.ref.Reference$Lock) at java.lang.Object.wait(Unknown Source) at java.lang.ref.Reference.tryHandlePending(Unknown Source) - locked <0x04406a90> (a java.lang.ref.Reference$Lock) at java.lang.ref.Reference$ReferenceHandler.run(Unknown Source) Locked ownable synchronizers: - None"VM Thread" os_prio=2 tid=0x00960c00 nid=0x2874 runnable"VM Periodic Task Thread" os_prio=2 tid=0x009e8000 nid=0x1664 waiting on conditionJNI global references: 6Found one Java-level deadlock:============================="Thread-1": waiting to lock monitor 0x009681c4 (object 0x044ab368, a java.lang.Object), which is held by "Thread-0""Thread-0": waiting to lock monitor 0x00969b94 (object 0x044ab370, a java.lang.Object), which is held by "Thread-1"Java stack information for the threads listed above:==================================================="Thread-1": at CyclicLock$2.run(CyclicLock.java:37) - waiting to lock <0x044ab368> (a java.lang.Object) - locked <0x044ab370> (a java.lang.Object) at java.lang.Thread.run(Unknown Source)"Thread-0": at CyclicLock$1.run(CyclicLock.java:20) - waiting to lock <0x044ab370> (a java.lang.Object) - locked <0x044ab368> (a java.lang.Object) at java.lang.Thread.run(Unknown Source)Found 1 deadlock.