Java線程轉儲和分析(jstack 命令)

代碼

下面代碼將產生一個死鎖。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發生死鎖

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章