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()也是这个状态。

    扫描二维码关注公众号,回复: 8566244 查看本文章
  • 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发生死锁

发布了92 篇原创文章 · 获赞 4 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/DingKG/article/details/103100627