1. 程式人生 > >Java死鎖以及命令檢測

Java死鎖以及命令檢測

阻塞 one found font pat rgs strong thread ron

Java每個對象都有一把鎖,當前進程使用對象鎖1,沒有釋放該鎖,又想要去獲取另一把對象鎖2,而對象鎖2被另外一個線程持有,沒有釋放,這就很容易出現死鎖

1.死鎖實例

public class DeadLockTest {

	private static Object object1 = new Object();
	private static Object object2 = new Object();

	public static void main(String[] args) {
		
		new Thread(new Runnable() {
			
			@Override
			public void run() {
				synchronized (object1) {
					System.out.println("線程1獲取object1鎖...");
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					synchronized (object2) {
						System.out.println("線程1獲取object2鎖...");
					}
				}
			}
		}).start();
		
		new Thread(new Runnable() {
			
			@Override
			public void run() {
				synchronized (object2) {
					System.out.println("線程2獲取object2鎖...");
					synchronized (object1) {
						System.out.println("線程2獲取object1鎖...");
					}
				}
			}
		}).start();
		
		System.out.println("main 線程執行完畢...");
	}
}

分析:線程1持有object1的鎖,同時又想去獲取object2的鎖,而此時線程2又持有object2的鎖沒有釋放,又想去獲取object1的鎖,這就造成了死鎖。

2.通過命令查看死鎖

前提:進入jdk的bin目錄下

2.1 jps

jps命令查看Java相關進程

技術分享圖片

2.2 jstack

jstack:查看分析具體的進程執行情況

運行上面的程序,執行jps命令,發現上面代碼的進程號為14888

然後執行jstack -l pid(進程號)

C:\Program Files\Java\jdk1.8.0_51\bin>jstack -l 14144
2018-07-15 23:44:43
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.51-b03 mixed mode):

"DestroyJavaVM" #13 prio=5 os_prio=0 tid=0x0000000004dd3800 nid=0x3808 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE

Locked ownable synchronizers:
- None

"Thread-1" #12 prio=5 os_prio=0 tid=0x000000001c1a1000 nid=0x2af4 waiting for monitor entry [0x000000001ce2f000]
java.lang.Thread.State: BLOCKED (on object monitor)
at com.liu.demo.test.thread.DeadLockTest$2.run(DeadLockTest.java:36)
- waiting to lock <0x00000000d60ba308> (a java.lang.Object)
- locked <0x00000000d60ba318> (a java.lang.Object)
at java.lang.Thread.run(Thread.java:745)

Locked ownable synchronizers:
- None

"Thread-0" #11 prio=5 os_prio=0 tid=0x000000001c1a0000 nid=0x6d0 waiting for monitor entry [0x000000001cd2f000]
java.lang.Thread.State: BLOCKED (on object monitor)
at com.liu.demo.test.thread.DeadLockTest$1.run(DeadLockTest.java:23)
- waiting to lock <0x00000000d60ba318> (a java.lang.Object)
- locked <0x00000000d60ba308> (a java.lang.Object)
at java.lang.Thread.run(Thread.java:745)

Locked ownable synchronizers:
- None

"Service Thread" #10 daemon prio=9 os_prio=0 tid=0x000000001c0df000 nid=0x2c0c runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE

Locked ownable synchronizers:
- None

"C1 CompilerThread3" #9 daemon prio=9 os_prio=2 tid=0x000000001c0c7000 nid=0x41ac waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE

Locked ownable synchronizers:
- None

"C2 CompilerThread2" #8 daemon prio=9 os_prio=2 tid=0x000000001c0bf800 nid=0x27e8 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE

Locked ownable synchronizers:
- None

"C2 CompilerThread1" #7 daemon prio=9 os_prio=2 tid=0x000000001c0be000 nid=0x3728 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE

Locked ownable synchronizers:
- None

"C2 CompilerThread0" #6 daemon prio=9 os_prio=2 tid=0x000000001c0b9800 nid=0x2f08 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE

Locked ownable synchronizers:
- None

"Attach Listener" #5 daemon prio=5 os_prio=2 tid=0x000000001c0b6800 nid=0x377c waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE

Locked ownable synchronizers:
- None

"Signal Dispatcher" #4 daemon prio=9 os_prio=2 tid=0x000000001c06a800 nid=0x1f48 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE

Locked ownable synchronizers:
- None

"Finalizer" #3 daemon prio=8 os_prio=1 tid=0x0000000004ecc000 nid=0x798 in Object.wait() [0x000000001bf2f000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x00000000d5f06f58> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143)
- locked <0x00000000d5f06f58> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:164)
at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:209)

Locked ownable synchronizers:
- None

"Reference Handler" #2 daemon prio=10 os_prio=2 tid=0x0000000004ec5000 nid=0x43ec in Object.wait() [0x000000001be2f000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x00000000d5f06998> (a java.lang.ref.Reference$Lock)
at java.lang.Object.wait(Object.java:502)
at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:157)
- locked <0x00000000d5f06998> (a java.lang.ref.Reference$Lock)

Locked ownable synchronizers:
- None

"VM Thread" os_prio=2 tid=0x0000000019f38000 nid=0x2f88 runnable

"GC task thread#0 (ParallelGC)" os_prio=0 tid=0x0000000004de9800 nid=0x1324 runnable

"GC task thread#1 (ParallelGC)" os_prio=0 tid=0x0000000004deb000 nid=0x1e24 runnable

"GC task thread#2 (ParallelGC)" os_prio=0 tid=0x0000000004dec800 nid=0x1bb4 runnable

"GC task thread#3 (ParallelGC)" os_prio=0 tid=0x0000000004dee000 nid=0x36c4 runnable

"GC task thread#4 (ParallelGC)" os_prio=0 tid=0x0000000004df0800 nid=0x3838 runnable

"GC task thread#5 (ParallelGC)" os_prio=0 tid=0x0000000004df2800 nid=0x1d2c runnable

"GC task thread#6 (ParallelGC)" os_prio=0 tid=0x0000000004df5800 nid=0x4214 runnable

"GC task thread#7 (ParallelGC)" os_prio=0 tid=0x0000000004df7000 nid=0x3018 runnable

"VM Periodic Task Thread" os_prio=2 tid=0x000000001c159000 nid=0x266c waiting on condition

JNI global references: 6


Found one Java-level deadlock:
=============================
"Thread-1":
waiting to lock monitor 0x0000000004eca3e8 (object 0x00000000d60ba308, a java.lang.Object),
which is held by "Thread-0"
"Thread-0":
waiting to lock monitor 0x0000000004ecb7d8 (object 0x00000000d60ba318, a java.lang.Object),
which is held by "Thread-1"

Java stack information for the threads listed above:
===================================================
"Thread-1":
at com.liu.demo.test.thread.DeadLockTest$2.run(DeadLockTest.java:36)
- waiting to lock <0x00000000d60ba308> (a java.lang.Object)
- locked <0x00000000d60ba318> (a java.lang.Object)
at java.lang.Thread.run(Thread.java:745)
"Thread-0":
at com.liu.demo.test.thread.DeadLockTest$1.run(DeadLockTest.java:23)
- waiting to lock <0x00000000d60ba318> (a java.lang.Object)
- locked <0x00000000d60ba308> (a java.lang.Object)
at java.lang.Thread.run(Thread.java:745)

Found 1 deadlock.

從上面的結果中可以看到,兩個線程都處於BLOCKED阻塞狀態,並且明確指出發現了一個死鎖;

Java死鎖以及命令檢測