jvm---6.2、jstack分析死锁

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
$ jps
15592 DeadLockTest


jstack 监控线程运行情况,使用-l参数打印出锁的情况
$ jstack -l 15592

日志如下:

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.
#找到一个死锁



猜你喜欢

转载自blog.csdn.net/convict_eva/article/details/80654883