代碼
下面代碼將產生一個死鎖。thread-1獲取lockA後,等待lockB,thread-2獲取lockB後,等待lockA。
public class {
private final static Lock lockA = new ReentrantLock();
private final static Lock lockB = new ReentrantLock();
public static void main(String[] args) {
Thread t1 = new Thread(() -> {
lockA.lock();
try {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("thread-1 "+" get lockA. try to get lockB");
lockB.lock();
} finally {
lockB.unlock();
lockA.unlock();
}
},"t1");
t1.start();
Thread t2 = new Thread(() -> {
lockB.lock();
try {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("thread-2 "+" get lockB. try to get lockA ");
lockA.lock();
} finally {
lockA.unlock();
lockB.unlock();
}
},"t2");
t2.start();
}
}
轉儲
1.使用jps -v
命令可以查看線程的pid
2.找到 ReentrantLockDeadLockTest對應的pid,這裏的是11623
3.使用jstack -l 11623 >> /Users/Desktop/threaddumps.log
命令進行轉儲。其中11623是進程號 /Users/Desktop/threaddumps.log是文件保存路徑(如果線程被掛起就使用jstack -F 11623 >> /Users/Desktop/threaddumps.log
)
結果分析
2019-11-16 17:15:41
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.201-b09 mixed mode):
"Attach Listener" #13 daemon prio=9 os_prio=31 tid=0x00007ff1de004000 nid=0xc07 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
Locked ownable synchronizers:
- None
"DestroyJavaVM" #12 prio=5 os_prio=31 tid=0x00007ff1de98b000 nid=0x2603 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
Locked ownable synchronizers:
- None
"t2" #11 prio=5 os_prio=31 tid=0x00007ff1de441000 nid=0x4103 waiting on condition [0x0000700008d9d000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000007958646d8> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:836)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:870)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1199)
at java.util.concurrent.locks.ReentrantLock$NonfairSync.lock(ReentrantLock.java:209)
at java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:285)
at com.edu.springboot.mybatis.testFile.ReentrantLockDeadLockTest.lambda$main$1(ReentrantLockDeadLockTest.java:47)
at com.edu.springboot.mybatis.testFile.ReentrantLockDeadLockTest$$Lambda$2/1496724653.run(Unknown Source)
at java.lang.Thread.run(Thread.java:748)
Locked ownable synchronizers:
- <0x0000000795864708> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
"t1" #10 prio=5 os_prio=31 tid=0x00007ff1de98a000 nid=0x3f03 waiting on condition [0x0000700008c9a000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x0000000795864708> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:836)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:870)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1199)
at java.util.concurrent.locks.ReentrantLock$NonfairSync.lock(ReentrantLock.java:209)
at java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:285)
at com.edu.springboot.mybatis.testFile.ReentrantLockDeadLockTest.lambda$main$0(ReentrantLockDeadLockTest.java:30)
at com.edu.springboot.mybatis.testFile.ReentrantLockDeadLockTest$$Lambda$1/683287027.run(Unknown Source)
at java.lang.Thread.run(Thread.java:748)
Locked ownable synchronizers:
- <0x00000007958646d8> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
"Service Thread" #9 daemon prio=9 os_prio=31 tid=0x00007ff1dd0f2000 nid=0x3b03 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
Locked ownable synchronizers:
- None
"C1 CompilerThread2" #8 daemon prio=9 os_prio=31 tid=0x00007ff1de2f9800 nid=0x3a03 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
Locked ownable synchronizers:
- None
"C2 CompilerThread1" #7 daemon prio=9 os_prio=31 tid=0x00007ff1dd0e1000 nid=0x4903 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
Locked ownable synchronizers:
- None
"C2 CompilerThread0" #6 daemon prio=9 os_prio=31 tid=0x00007ff1dd8d1800 nid=0x4a03 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
Locked ownable synchronizers:
- None
"Monitor Ctrl-Break" #5 daemon prio=5 os_prio=31 tid=0x00007ff1de2f9000 nid=0x3703 runnable [0x0000700008688000]
java.lang.Thread.State: RUNNABLE
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
at java.net.SocketInputStream.read(SocketInputStream.java:171)
at java.net.SocketInputStream.read(SocketInputStream.java:141)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
- locked <0x00000007958fcaf0> (a java.io.InputStreamReader)
at java.io.InputStreamReader.read(InputStreamReader.java:184)
at java.io.BufferedReader.fill(BufferedReader.java:161)
at java.io.BufferedReader.readLine(BufferedReader.java:324)
- locked <0x00000007958fcaf0> (a java.io.InputStreamReader)
at java.io.BufferedReader.readLine(BufferedReader.java:389)
at com.intellij.rt.execution.application.AppMainV2$1.run(AppMainV2.java:64)
Locked ownable synchronizers:
- None
"Signal Dispatcher" #4 daemon prio=9 os_prio=31 tid=0x00007ff1dd81d000 nid=0x3603 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
Locked ownable synchronizers:
- None
"Finalizer" #3 daemon prio=8 os_prio=31 tid=0x00007ff1dd813000 nid=0x4f03 in Object.wait() [0x0000700008482000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x0000000795588ed0> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:144)
- locked <0x0000000795588ed0> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:165)
at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:216)
Locked ownable synchronizers:
- None
"Reference Handler" #2 daemon prio=10 os_prio=31 tid=0x00007ff1dd015800 nid=0x2e03 in Object.wait() [0x000070000837f000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x0000000795586bf8> (a java.lang.ref.Reference$Lock)
at java.lang.Object.wait(Object.java:502)
at java.lang.ref.Reference.tryHandlePending(Reference.java:191)
- locked <0x0000000795586bf8> (a java.lang.ref.Reference$Lock)
at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153)
Locked ownable synchronizers:
- None
"VM Thread" os_prio=31 tid=0x00007ff1de025800 nid=0x2d03 runnable
"GC task thread#0 (ParallelGC)" os_prio=31 tid=0x00007ff1dd007800 nid=0x1e07 runnable
"GC task thread#1 (ParallelGC)" os_prio=31 tid=0x00007ff1dd008800 nid=0x2a03 runnable
"GC task thread#2 (ParallelGC)" os_prio=31 tid=0x00007ff1dd80e800 nid=0x5303 runnable
"GC task thread#3 (ParallelGC)" os_prio=31 tid=0x00007ff1de00d000 nid=0x2b03 runnable
"VM Periodic Task Thread" os_prio=31 tid=0x00007ff1dd12a800 nid=0x3d03 waiting on condition
JNI global references: 320
Found one Java-level deadlock:
=============================
"t2":
waiting for ownable synchronizer 0x00000007958646d8, (a java.util.concurrent.locks.ReentrantLock$NonfairSync),
which is held by "t1"
"t1":
waiting for ownable synchronizer 0x0000000795864708, (a java.util.concurrent.locks.ReentrantLock$NonfairSync),
which is held by "t2"
Java stack information for the threads listed above:
===================================================
"t2":
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000007958646d8> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:836)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:870)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1199)
at java.util.concurrent.locks.ReentrantLock$NonfairSync.lock(ReentrantLock.java:209)
at java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:285)
at com.edu.springboot.mybatis.testFile.ReentrantLockDeadLockTest.lambda$main$1(ReentrantLockDeadLockTest.java:47)
at com.edu.springboot.mybatis.testFile.ReentrantLockDeadLockTest$$Lambda$2/1496724653.run(Unknown Source)
at java.lang.Thread.run(Thread.java:748)
"t1":
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x0000000795864708> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:836)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:870)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1199)
at java.util.concurrent.locks.ReentrantLock$NonfairSync.lock(ReentrantLock.java:209)
at java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:285)
at com.edu.springboot.mybatis.testFile.ReentrantLockDeadLockTest.lambda$main$0(ReentrantLockDeadLockTest.java:30)
at com.edu.springboot.mybatis.testFile.ReentrantLockDeadLockTest$$Lambda$1/683287027.run(Unknown Source)
at java.lang.Thread.run(Thread.java:748)
Found 1 deadlock.
t1爲例
"t1" #10 prio=5 os_prio=31 tid=0x00007ff1de98a000 nid=0x3f03 waiting on condition [0x0000700008c9a000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x0000000795864708> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:836)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:870)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1199)
at java.util.concurrent.locks.ReentrantLock$NonfairSync.lock(ReentrantLock.java:209)
at java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:285)
at com.edu.springboot.mybatis.testFile.ReentrantLockDeadLockTest.lambda$main$0(ReentrantLockDeadLockTest.java:30)
at com.edu.springboot.mybatis.testFile.ReentrantLockDeadLockTest$$Lambda$1/683287027.run(Unknown Source)
at java.lang.Thread.run(Thread.java:748)
Locked ownable synchronizers:
- <0x00000007958646d8> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
1.“t1”:線程名字
2.如果有daemon,表示爲守護線程,t1不是守護線程,所有沒有daemon
3.prio=5:線程優先級,默認是5
4.tid=0x00007ff1de98a000:Java的線程Id(線程在當前虛擬機中的唯一標識)
5.nid=0x3f03:線程本地標識,是線程在操作系統中的標識.
6.waiting on condition:線程DUMP的狀態。一般有如下幾種狀態:
-
Deadlock:死鎖(使用內置鎖鎖時出現)
-
Runnable: 線程正在運行中。一般指該線程正在執行狀態中,該線程佔用了資源,正在處理某個請求。
-
Wait on condition:該狀態表示線程在等待資源,或等待某個條件的發生。比如:該線程在 sleep,等待 sleep的時間到了時候,將被喚醒; 等待I/O;調用了有超時參數的wait。用ReentrantLock獲取鎖等待的時候是這個狀態,ReentrantLock的condition.await()也是這個狀態。
-
Waiting for monitor entry:線程沒有獲取過鎖,在等待獲取鎖。用synchronized獲取鎖等待的時候是這個狀態(在鎖池的線程)。
-
in Object.wait():線程已獲取鎖,處於運行狀態,但又執行了Object.wait()方法將鎖釋放掉,並仍然等待該鎖(在等待池的線程)。
-
Blocked:線程阻塞,是指當前線程執行過程中,所需要的資源長時間等待卻一直未能獲取到,被容器的線程管理器標識爲阻塞狀態,可以理解爲等待資源超時的線程。
-
Suspended:暫停
-
Parked:停止
7.[0x0000700008c9a000]:當前運行的線程在堆中的地址範圍
8.java.lang.Thread.State: WAITING (parking):線程狀態是WAITING ,它是被parking掛起了
9.- parking to wait for <0x0000000795864708> (a java.util.concurrent.locks.ReentrantLock$NonfairSync):它被parking掛起,等待獲取一個ReentrantLock的非公平鎖(非公平是NonfairSync,公平是FairSync。)0x0000000795864708
10.Locked ownable synchronizers: - <0x00000007958646d8> (a java.util.concurrent.locks.ReentrantLock$NonfairSync):它已經擁有的鎖是一個ReentrantLock的非公平鎖0x00000007958646d8
檢測到死鎖
在轉碼文件中有這樣一段:
Found one Java-level deadlock:
=============================
"t2":
waiting for ownable synchronizer 0x00000007958646d8, (a java.util.concurrent.locks.ReentrantLock$NonfairSync),
which is held by "t1"
"t1":
waiting for ownable synchronizer 0x0000000795864708, (a java.util.concurrent.locks.ReentrantLock$NonfairSync),
which is held by "t2"
Java stack information for the threads listed above:
翻譯過來就是t2在等待非公平鎖0x00000007958646d8,該鎖現在在被t1持有;t1在等待非公平鎖0x0000000795864708,該鎖現在在被t2持有;
可以很明顯的看出t1和t2發生死鎖