【多线程】死锁与Java栈跟踪工具

今天面试有一道题,写一个死锁的程序,自己也是短路了,没写出来,回来写下。

死锁常见的情况是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>jps
11168 CyclicLock
3504
10204 Jps

C:\Users\Administrator>
C:\Users\Administrator>jstack -l 11168
2017-03-22 23:24:24
Full 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 [0
x00000000]
   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 [0x
15f2f000]
   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 [0x
15bff000]
   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 [0x0000
0000]
   java.lang.Thread.State: RUNNABLE

   Locked ownable synchronizers:
        - None

"C1 CompilerThread0" #6 daemon prio=9 os_prio=2 tid=0x009dfc00 nid=0x2278 waiting on c
ondition [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 cond
ition [0x00000000]
   java.lang.Thread.State: RUNNABLE

   Locked ownable synchronizers:
        - None

"Signal Dispatcher" #4 daemon prio=9 os_prio=2 tid=0x009db400 nid=0x52c runnable [0x00
000000]
   java.lang.Thread.State: RUNNABLE

   Locked ownable synchronizers:
        - None

"Finalizer" #3 daemon prio=8 os_prio=1 tid=0x009c0c00 nid=0x2214 in Object.wait() [0x1
56bf000]
   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.wa
it() [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 condition

JNI global references: 6


Found 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.
posted @ 2017-04-18 21:19  nick_huang  阅读(906)  评论(0编辑  收藏  举报