jstack分析死锁
写一个死锁:
先写两个锁,LockA, LockB。 在LockA 的opt 方法中调用LockB 方法,在LockB 的opt 方法中调用LockA 的opt 方法
/**
* A锁
*/
public class LockA {
Lock lock = new ReentrantLock();
public void opt(LockB b){
//A 锁
lock.lock();
try{
TimeUnit.SECONDS.sleep(20);
//B 锁
b.opt(this);
}catch (Exception e){
}finally {
lock.unlock();
}
}
}
/**
* B 锁
*/
public class LockB {
Lock lock = new ReentrantLock();
public void opt(LockA a){
//B 锁
lock.lock();
try{
TimeUnit.SECONDS.sleep(10);
//A锁
a.opt(this);
}catch (Exception e){
}finally {
lock.unlock();
}
}
}
//测试代码:
public static void main(String[] args) {
//构造LockA lockB
LockA a = new LockA();
LockB b = new LockB();
//线程2,先获取LockA的锁,再获取LockB的锁
Thread t1 = new Thread(){
@Override
public void run() {
a.opt(b);
}
};
//设置线程名
t1.setName("thread t1");
t1.start();
//线程2,先获取LockB的锁,再获取LockA的锁
Thread t2 = new Thread(){
@Override
public void run() {
b.opt(a);
}
};
//设置线程名
t2.setName("thread t2");
t2.start();
}
使用jps 找到pid
2018-06-11 16:51:18
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.144-b01 mixed mode):
#日志生成时间,及虚拟机信息
"DestroyJavaVM" #14 prio=5 os_prio=0 tid=0x00000000029aa800 nid=0xaf0 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
Locked ownable synchronizers:
- None
"thread t2" #13 prio=5 os_prio=0 tid=0x000000001fbd9000 nid=0x33c8 waiting on condition [0x0000000020d8f000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x000000076b2617d0> (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.masz.lock.LockA.opt(LockA.java:16)
at com.masz.lock.LockB.opt(LockB.java:20)
at com.masz.lock.DeadLockTest$2.run(DeadLockTest.java:27)
Locked ownable synchronizers:
- <0x000000076b2639c8> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
#线程名是代码中定义的线程名 thread t2。线程状态是 WAITING (parking)。
#parking to wait for <0x000000076b2617d0>(...) 说明等待 0x000000076b2617d0 这个对象,后面括号是对象的类型,说明是等待的是ReentrantLock
#最后一行是说明拥有锁 0x000000076b2639c8(这个是内存的地址)
"thread t1" #12 prio=5 os_prio=0 tid=0x000000001fbd8800 nid=0x1518 waiting on condition [0x0000000020c8e000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x000000076b2639c8> (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.masz.lock.LockB.opt(LockB.java:16)
at com.masz.lock.LockA.opt(LockA.java:20)
at com.masz.lock.DeadLockTest$1.run(DeadLockTest.java:16)
Locked ownable synchronizers:
- <0x000000076b2617d0> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
#和 thread t2 一样,就是等待的对象和拥有锁的对象地址不同
"Service Thread" #11 daemon prio=9 os_prio=0 tid=0x000000001f3c6000 nid=0x2050 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
Locked ownable synchronizers:
- None
..... 省略了一些其它的线程信息
"GC task thread#7 (ParallelGC)" os_prio=0 tid=0x00000000029ce000 nid=0x12d0 runnable
"VM Periodic Task Thread" os_prio=2 tid=0x000000001f49b000 nid=0xdc waiting on condition
JNI global references: 33
Found one Java-level deadlock:
=============================
"thread t2":
waiting for ownable synchronizer 0x000000076b2617d0, (a java.util.concurrent.locks.ReentrantLock$NonfairSync),
which is held by "thread t1"
"thread t1":
waiting for ownable synchronizer 0x000000076b2639c8, (a java.util.concurrent.locks.ReentrantLock$NonfairSync),
which is held by "thread t2"
#发现了 deadlock
#thread t2 线程 等待同步对象 0x000000076b2617d0 的拥有者 thread t1
#thread t1 线程 等待同步对象 0x000000076b2639c8 的拥有者 thread t2
Java stack information for the threads listed above:
#对死锁线程的 stack information
===================================================
"thread t2":
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x000000076b2617d0> (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.masz.lock.LockA.opt(LockA.java:16)
at com.masz.lock.LockB.opt(LockB.java:20)
at com.masz.lock.DeadLockTest$2.run(DeadLockTest.java:27)
"thread t1":
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x000000076b2639c8> (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.masz.lock.LockB.opt(LockB.java:16)
at com.masz.lock.LockA.opt(LockA.java:20)
at com.masz.lock.DeadLockTest$1.run(DeadLockTest.java:16)
Found 1 deadlock.
#找到一个死锁