代码
下面代码将产生一个死锁。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发生死锁