一、thread dump信息获取
1、发送信号
* In Unix, use "kill -3
* In Windows, press CTRL+BREAK on the window where the JVM is running.
2、通过命令导出文本文件
jps -l 找出服务器上运行的Java进程
jstack -l pid 直接显示在屏幕上
jstack pid | tee -a jstack.log 导出堆栈文件
3、通过jdk工具jvisualvm,在界面上点击生成thread dump文件
二、分析thread dump信息
1、最上面的是时间和jvm的信息
2、各个线程thread信息
3、最后面是heap堆的信息
三、thread线程的原始状态和thread dump文件中线程状态的
1、thread线程的原始状态:
NEW:还没有调用start()方法开始执行,在thread dump中不会出现
RUNNABLE:正常在执行的线程
BLOCKED:阻塞状态,等待获取锁进入同步方法或者同步代码块
WAITING:调用wait(),join(),LockSupport.park()方法
TIMED_WAITING:调用wait(long),join(long),LockSupport.parkNanos,LockSupport.parkUntil方法,在指定时间内等待并且没有超时
TERMINATED:正常执行完的线程,在thread dump中不会出现
在thread dump中可能出现的thread线程的原始状态有:RUNNABLE,BLOCKED,WAITING,TIMED_WAITING
2、thread dump文件中线程状态的种类:
Runnable
sleeping
Waiting for monitor entry (重点关注)
Wait on condition(重点关注)
in Object.wait() (重点关注)
Deadlock(重点关注)
其中
thread的RUNNABLE对应---> Runnable
thread的BLOCKED对应---> Waiting for monitor entry
thread的WAITING和TIMED_WAITING对应---> in Object.wait()和Wait on condition
四、Dump文件中的线程状态含义:
Deadlock:死锁线程,一般指多个线程调用间,进入相互资源占用,导致一直等待无法释放的情况。
Runnable:一般指该线程正在执行状态中,该线程占用了资源,正在处理某个请求,有可能正在传递SQL到数据库执行,有可能在对某个文件操作,有可能进行数据类型等转换。
Waiting on condition:等待资源,或等待某个条件的发生。具体原因需结合 stacktrace来分析。如果堆栈信息明确是应用代码,则证明该线程正在等待资源。一般是大量读取某资源,且该资源采用了资源锁的情况下,线程进入等待状态,等待资源的读取。又或者,正在等待其他线程的执行等。
如果发现有大量的线程都在处在 Wait on condition,从线程 stack看,正等待网络读写,这可能是一个网络瓶颈的征兆。因为网络阻塞导致线程无法执行。一种情况是网络非常忙,几乎消耗了所有的带宽,仍然有大量数据等待网络读写;
另一种情况也可能是网络空闲,但由于路由等问题,导致包无法正常的到达。
另外一种出现 Wait on condition的常见情况是该线程在 sleep,等待 sleep的时间到了时候,将被唤醒。
Blocked:线程阻塞,是指当前线程执行过程中,所需要的资源长时间等待却一直未能获取到,被容器的线程管理器标识为阻塞状态,可以理解为等待资源超时的线程。
Waiting for monitor entry 和 in Object.wait():Monitor是 Java中用以实现线程之间的互斥与协作的主要手段,它可以看成是对象或者 Class的锁。
每一个对象都有,也仅有一个 monitor。每个 Monitor在某个时刻,只能被一个线程拥有,该线程就是 “Active Thread”,
而其它线程都是 “Waiting Thread”,分别在两个队列 “ Entry Set”和 “Wait Set”里面等候。
在 “Entry Set”中等待的线程状态是 “Waiting for monitor entry”,而在 “Wait Set”中等待的线程状态是 “in Object.wait()”。
在 “Entry Set”中的是试图获取锁而阻塞的线程;而“Wait Set”则是,获取锁后调用wait()而进入阻塞的线程,当其他线程调用notify()或者notifyall()唤醒等待该锁上的其他线程时,会把“Wait Set”队列中的
一个或者全部线程放入“Entry Set”中,然后在其中随机选择一个重新获取锁,然后执行。
一个阻塞状态线程的分析:
1. "Timer-0" daemon prio=10 tid=0xac190c00 nid=0xaef in Object.wait() [0xae77d000]
2. java.lang.Thread.State: TIMED_WAITING (on object monitor)
3. atjava.lang.Object.wait(Native Method)
4. -waiting on <0xb3885f60> (a java.util.TaskQueue) ###继续wait
5. atjava.util.TimerThread.mainLoop(Timer.java:509)
6. -locked <0xb3885f60> (a java.util.TaskQueue) ###已经locked
7. atjava.util.TimerThread.run(Timer.java:462)
* 线程名称:Timer-0
* 线程类型:daemon
* 优先级: 10,默认是5
* jvm线程id:tid=0xac190c00,jvm内部线程的唯一标识(通过java.lang.Thread.getId()获取,通常用自增方式实现。)
* 对应系统线程id(NativeThread ID):nid=0xaef,和top命令查看的线程pid对应,不过一个是10进制,一个是16进制。(通过命令:top -H -p pid,可以查看该进程的所有线程信息)
* 线程状态:in Object.wait().
* 起始栈地址:[0xae77d000]
* Java thread statck trace:是上面2-7行的信息。到目前为止这是最重要的数据,Java stack trace提供了大部分信息来精确定位问题根源。(倒着看,入口在最下面一行)
JNI global references表示的意义?
五、案例分析
综合案例一:BLOCKED---waiting for monitor entry(deadlock)
综合案例二:BLOCKED---waiting for monitor entry(热点同步代码块造成的阻塞)
综合案例三:WAITING---(in Object.wait())(调用 object.wait()造成的)
综合案例四:TIMED_WAITING--- in Object.wait()(object.wait(1 * 60 * 1000)造成)
综合案例五:WAITING (parking)---waiting on condition(通过条件变量condition.await()造成)
综合案例六:TIMED_WAITING (parking)---waiting on condition(通过条件变量condition.await(5, TimeUnit.MINUTES)造成)
综合案例七:TIMED_WAITING---waiting on condition(Thread.sleep(1*60*1000)造成的)
综合案例一:BLOCKED---waiting for monitor entry(deadlock)
public class Test {
public static void main(String[] args) throws Exception{
System.out.println("主线程开始"+Thread.currentThread().getName());
final LeftRightDeadLock lock = new LeftRightDeadLock();
Thread t1 = new Thread(){
@Override
public void run() {
try {
lock.leftRight();
} catch (Exception e) {
e.printStackTrace();
}
}
};
Thread t2 = new Thread(){
@Override
public void run() {
try {
lock.rightLeft();
} catch (Exception e) {
e.printStackTrace();
}
}
};
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println("主线程结束"+Thread.currentThread().getName());
}
}
public class LeftRightDeadLock {
private final Object left = new Object();
private final Object right = new Object();
public void leftRight() throws Exception {
synchronized (left) {
System.out.println(Thread.currentThread().getName()+"获得left锁");
Thread.sleep(1000);
synchronized (right)
{
System.out.println("leftRight end!");
}
}
}
public void rightLeft() throws Exception {
synchronized (right) { System.out.println(Thread.currentThread().getName()+"获得right锁");
Thread.sleep(1000);
synchronized (left)
{
System.out.println("rightLeft end!");
}
}
}
}
thread dump信息:
"Thread-1" prio=6 tid=0x000000000c019000 nid=0x2f38 waiting for monitor entry [0x000000000d14f000]
java.lang.Thread.State: BLOCKED (on object monitor)
at ls.lock.LeftRightDeadLock.rightLeft(LeftRightDeadLock.java:32)
- waiting to lock <0x00000000d7d53bb8> (a java.lang.Object)
- locked <0x00000000d7d53bc8> (a java.lang.Object)
at ls.lock.Test$2.run(Test.java:26)
"Thread-0" prio=6 tid=0x000000000c018000 nid=0x3de0 waiting for monitor entry [0x000000000cddf000]
java.lang.Thread.State: BLOCKED (on object monitor)
at ls.lock.LeftRightDeadLock.leftRight(LeftRightDeadLock.java:20)
- waiting to lock <0x00000000d7d53bc8> (a java.lang.Object)
- locked <0x00000000d7d53bb8> (a java.lang.Object)
at ls.lock.Test$1.run(Test.java:16)
Found one Java-level deadlock:
=============================
"Thread-1":
waiting to lock monitor 0x000000000aa87f58 (object 0x00000000d7d53bb8, a java.lang.Object),
which is held by "Thread-0"
"Thread-0":
waiting to lock monitor 0x000000000c01ad08 (object 0x00000000d7d53bc8, a java.lang.Object),
which is held by "Thread-1"
综合案例二:BLOCKED---waiting for monitor entry(热点同步代码块造成的阻塞)
public class BlockedState {
private static Object object = new Object();
public static void main(String[] args) {
Runnable task = new Runnable() {
@Override
public void run() {
synchronized (object) {
System.out.println("线程:" + Thread.currentThread().getName()+"获取锁");
long begin = System.currentTimeMillis();
long end = System.currentTimeMillis();
// 让线程运行1分钟,会一直持有object的监视器
while ((end - begin) <= 1 * 60 * 1000) {
end = System.currentTimeMillis();
}
}
}
};
new Thread(task, "t1").start();
new Thread(task, "t2").start();
}
}
thread dump信息:
"t2" prio=6 tid=0x000000000c389800 nid=0x3ee4 waiting for monitor entry [0x000000000cc6f000]
java.lang.Thread.State: BLOCKED (on object monitor)
at ls.lock.BlockedState$1.run(BlockedState.java:19)
- waiting to lock <0x00000000d7d4c460> (a java.lang.Object)
at java.lang.Thread.run(Thread.java:744)
"t1" prio=6 tid=0x000000000c388800 nid=0x3d08 runnable [0x000000000cf0e000]
java.lang.Thread.State: RUNNABLE
at ls.lock.BlockedState$1.run(BlockedState.java:24)
- locked <0x00000000d7d4c460> (a java.lang.Object)
at java.lang.Thread.run(Thread.java:744)
综合案例三:WAITING---(in Object.wait())(调用 object.wait()造成的)
public class WaitingState {
private static Object object = new Object();
public static void main(String[] args) {
Runnable task = new Runnable() {
@Override
public void run() {
synchronized (object) {
System.out.println("线程:" + Thread.currentThread().getName()+"获取锁");
try {
object.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
new Thread(task, "t1").start();
new Thread(task, "t2").start();
}
}
thread dump信息:
"t2" prio=6 tid=0x000000000c379800 nid=0x3e28 in Object.wait() [0x000000000d06f000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x00000000d7d4c4a0> (a java.lang.Object)
at java.lang.Object.wait(Object.java:503)
at ls.lock.WaitingState$1.run(WaitingState.java:29)
- locked <0x00000000d7d4c4a0> (a java.lang.Object)
at java.lang.Thread.run(Thread.java:744)
"t1" prio=6 tid=0x000000000c375000 nid=0x3f54 in Object.wait() [0x000000000d18f000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x00000000d7d4c4a0> (a java.lang.Object)
at java.lang.Object.wait(Object.java:503)
at ls.lock.WaitingState$1.run(WaitingState.java:29)
- locked <0x00000000d7d4c4a0> (a java.lang.Object)
at java.lang.Thread.run(Thread.java:744)
综合案例四:TIMED_WAITING--- in Object.wait()(object.wait(1 * 60 * 1000)造成)
public class TimedWaitingState1 {
private static Object object = new Object();
public static void main(String[] args) {
Runnable task = new Runnable() {
@Override
public void run() {
synchronized (object) {
System.out.println("线程:" + Thread.currentThread().getName()+"获取锁");
try {
// 进入等待的同时,会进入释放监视器
object.wait(1 * 60 * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
new Thread(task, "t1").start();
new Thread(task, "t2").start();
}
}
thread dump信息:
"t2" prio=6 tid=0x000000000c0e5000 nid=0x3788 in Object.wait() [0x000000000cf9f000]
java.lang.Thread.State: TIMED_WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x00000000d7d4c978> (a java.lang.Object)
at ls.lock.TimedWaitingState1$1.run(TimedWaitingState1.java:26)
- locked <0x00000000d7d4c978> (a java.lang.Object)
at java.lang.Thread.run(Thread.java:744)
"t1" prio=6 tid=0x000000000c0b9000 nid=0x31a8 in Object.wait() [0x000000000cddf000]
java.lang.Thread.State: TIMED_WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x00000000d7d4c978> (a java.lang.Object)
at ls.lock.TimedWaitingState1$1.run(TimedWaitingState1.java:26)
- locked <0x00000000d7d4c978> (a java.lang.Object)
at java.lang.Thread.run(Thread.java:744)
综合案例五:WAITING (parking)---waiting on condition(通过条件变量condition.await()造成)
public class TimedWaitingState3 {
// java的显示锁,类似java对象内置的监视器
private static Lock lock = new ReentrantLock();
// 锁关联的条件队列(类似于object.wait)
private static Condition condition = lock.newCondition();
public static void main(String[] args) {
Runnable task = new Runnable() {
@Override
public void run() {
// 加锁,进入临界区
lock.lock();
System.out.println("线程:" + Thread.currentThread().getName()+"获取锁");
try {
condition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
// 解锁,退出临界区
lock.unlock();
}
};
new Thread(task, "t1").start();
new Thread(task, "t2").start();
}
}
thread dump信息:
"t2" prio=6 tid=0x000000000c3ae800 nid=0x3f1c waiting on condition [0x000000000d03f000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000000d7d4ef90> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2043)
at ls.lock.TimedWaitingState3$1.run(TimedWaitingState3.java:51)
at java.lang.Thread.run(Thread.java:744)
"t1" prio=6 tid=0x000000000c3ad800 nid=0x36a4 waiting on condition [0x000000000cdbe000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000000d7d4ef90> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2043)
at ls.lock.TimedWaitingState3$1.run(TimedWaitingState3.java:51)
at java.lang.Thread.run(Thread.java:744)
综合案例六:TIMED_WAITING (parking)---waiting on condition(通过条件变量condition.await(5, TimeUnit.MINUTES)造成)
public class TimedWaitingState {
// java的显示锁,类似java对象内置的监视器
private static Lock lock = new ReentrantLock();
// 锁关联的条件队列(类似于object.wait)
private static Condition condition = lock.newCondition();
public static void main(String[] args) {
Runnable task = new Runnable() {
@Override
public void run() {
// 加锁,进入临界区
lock.lock();
System.out.println("线程:" + Thread.currentThread().getName()+"获取锁");
try {
condition.await(5, TimeUnit.MINUTES);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 解锁,退出临界区
lock.unlock();
}
};
new Thread(task, "t1").start();
new Thread(task, "t2").start();
}
}
thread dump信息:
"t2" prio=6 tid=0x000000000c321000 nid=0x3bb4 waiting on condition [0x000000000d28f000]
java.lang.Thread.State: TIMED_WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000000d7d4ed18> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:226)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2176)
at ls.lock.TimedWaitingState$1.run(TimedWaitingState.java:31)
at java.lang.Thread.run(Thread.java:744)
"t1" prio=6 tid=0x000000000c320800 nid=0x3d64 waiting on condition [0x000000000d05e000]
java.lang.Thread.State: TIMED_WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000000d7d4ed18> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:226)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2176)
at ls.lock.TimedWaitingState$1.run(TimedWaitingState.java:31)
at java.lang.Thread.run(Thread.java:744)
综合案例七:TIMED_WAITING---waiting on condition(Thread.sleep(1*60*1000)造成的)
public class TimedWaitingState2 {
public static void main(String[] args) {
Runnable task = new Runnable() {
@Override
public void run() {
System.out.println("线程:" + Thread.currentThread().getName()+"获取锁");
try {
Thread.sleep(1*60*1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
new Thread(task, "t1").start();
new Thread(task, "t2").start();
}
}
thread dump信息:
"t2" prio=6 tid=0x000000000c632000 nid=0x3f14 waiting on condition [0x000000000d20f000]
java.lang.Thread.State: TIMED_WAITING (sleeping)
at java.lang.Thread.sleep(Native Method)
at ls.lock.WaitOnCondition$1.run(WaitOnCondition.java:17)
at java.lang.Thread.run(Thread.java:744)
"t1" prio=6 tid=0x000000000c551000 nid=0xae8 waiting on condition [0x000000000d07e000]
java.lang.Thread.State: TIMED_WAITING (sleeping)
at java.lang.Thread.sleep(Native Method)
at ls.lock.WaitOnCondition$1.run(WaitOnCondition.java:17)
at java.lang.Thread.run(Thread.java:744)
附录:
死锁测试代码
public class LeftRightDeadLock
{
private final Object left = new Object();
private final Object right = new Object();
public void leftRight() throws Exception
{
synchronized (left)
{
System.out.println(Thread.currentThread().getName()+"获得left锁");
Thread.sleep(1000);
synchronized (right)
{
System.out.println("leftRight end!");
}
}
}
public void rightLeft() throws Exception
{
synchronized (right)
{ System.out.println(Thread.currentThread().getName()+"获得right锁");
Thread.sleep(1000);
synchronized (left)
{
System.out.println("rightLeft end!");
}
}
}
}
public class Test {
public static void main(String[] args) throws Exception{
System.out.println("主线程开始"+Thread.currentThread().getName());
final LeftRightDeadLock lock = new LeftRightDeadLock();
Thread t1 = new Thread(){
@Override
public void run() {
try {
lock.leftRight();
} catch (Exception e) {
e.printStackTrace();
}
}
};
Thread t2 = new Thread(){
@Override
public void run() {
try {
lock.rightLeft();
} catch (Exception e) {
e.printStackTrace();
}
}
};
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println("主线程结束"+Thread.currentThread().getName());
}
}
程序运行输出:
主线程开始main
Thread-1获得right锁
Thread-0获得left锁
thread dump文件
2018-07-30 16:24:06
Full thread dump Java HotSpot(TM) 64-Bit Server VM (24.51-b03 mixed mode):
"Thread-1" prio=6 tid=0x000000000c4ee000 nid=0x2ffc waiting for monitor entry [0x000000000d0ef000]
java.lang.Thread.State: BLOCKED (on object monitor)
at ls.lock.LeftRightDeadLock.rightLeft(LeftRightDeadLock.java:32)
- waiting to lock <0x00000000d7d53ca8> (a java.lang.Object)
- locked <0x00000000d7d53cb8> (a java.lang.Object)
at ls.lock.Test$2.run(Test.java:25)
"Thread-0" prio=6 tid=0x000000000c4ed800 nid=0x46f0 waiting for monitor entry [0x000000000d21f000]
java.lang.Thread.State: BLOCKED (on object monitor)
at ls.lock.LeftRightDeadLock.leftRight(LeftRightDeadLock.java:20)
- waiting to lock <0x00000000d7d53cb8> (a java.lang.Object)
- locked <0x00000000d7d53ca8> (a java.lang.Object)
at ls.lock.Test$1.run(Test.java:15)
"Service Thread" daemon prio=6 tid=0x000000000c3c9800 nid=0x31a0 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C2 CompilerThread1" daemon prio=10 tid=0x000000000c3c8800 nid=0x430c waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C2 CompilerThread0" daemon prio=10 tid=0x000000000c3c7800 nid=0x2a48 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Monitor Ctrl-Break" daemon prio=6 tid=0x000000000c3bf800 nid=0x48ac runnable [0x000000000c95f000]
java.lang.Thread.State: RUNNABLE
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:152)
at java.net.SocketInputStream.read(SocketInputStream.java:122)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:283)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:325)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:177)
- locked <0x00000000d7e12a50> (a java.io.InputStreamReader)
at java.io.InputStreamReader.read(InputStreamReader.java:184)
at java.io.BufferedReader.fill(BufferedReader.java:154)
at java.io.BufferedReader.readLine(BufferedReader.java:317)
- locked <0x00000000d7e12a50> (a java.io.InputStreamReader)
at java.io.BufferedReader.readLine(BufferedReader.java:382)
at com.intellij.rt.execution.application.AppMainV2$1.run(AppMainV2.java:64)
"Attach Listener" daemon prio=10 tid=0x000000000ac3f800 nid=0x3e48 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Signal Dispatcher" daemon prio=10 tid=0x000000000abda000 nid=0x3a20 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Finalizer" daemon prio=8 tid=0x000000000abc2800 nid=0x31f0 in Object.wait() [0x000000000bb8f000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x00000000d7c05568> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:135)
- locked <0x00000000d7c05568> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:151)
at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:189)
"Reference Handler" daemon prio=10 tid=0x000000000abbf000 nid=0x2354 in Object.wait() [0x000000000beaf000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x00000000d7c050f0> (a java.lang.ref.Reference$Lock)
at java.lang.Object.wait(Object.java:503)
at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:133)
- locked <0x00000000d7c050f0> (a java.lang.ref.Reference$Lock)
"main" prio=6 tid=0x00000000024e9000 nid=0x48dc in Object.wait() [0x00000000029cf000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x00000000d7d53cc8> (a ls.lock.Test$1)
at java.lang.Thread.join(Thread.java:1280)
- locked <0x00000000d7d53cc8> (a ls.lock.Test$1)
at java.lang.Thread.join(Thread.java:1354)
at ls.lock.Test.main(Test.java:34)
"VM Thread" prio=10 tid=0x000000000abbd800 nid=0x40e8 runnable
"GC task thread#0 (ParallelGC)" prio=6 tid=0x00000000024ff000 nid=0x40c0 runnable
"GC task thread#1 (ParallelGC)" prio=6 tid=0x0000000002501000 nid=0x4064 runnable
"GC task thread#2 (ParallelGC)" prio=6 tid=0x0000000002502800 nid=0x437c runnable
"GC task thread#3 (ParallelGC)" prio=6 tid=0x0000000002504800 nid=0x1270 runnable
"VM Periodic Task Thread" prio=10 tid=0x000000000c3cd800 nid=0x34d4 waiting on condition
JNI global references: 127
Found one Java-level deadlock:
=============================
"Thread-1":
waiting to lock monitor 0x000000000c4eff28 (object 0x00000000d7d53ca8, a java.lang.Object),
which is held by "Thread-0"
"Thread-0":
waiting to lock monitor 0x000000000abc96e8 (object 0x00000000d7d53cb8, a java.lang.Object),
which is held by "Thread-1"
Java stack information for the threads listed above:
===================================================
"Thread-1":
at ls.lock.LeftRightDeadLock.rightLeft(LeftRightDeadLock.java:32)
- waiting to lock <0x00000000d7d53ca8> (a java.lang.Object)
- locked <0x00000000d7d53cb8> (a java.lang.Object)
at ls.lock.Test$2.run(Test.java:25)
"Thread-0":
at ls.lock.LeftRightDeadLock.leftRight(LeftRightDeadLock.java:20)
- waiting to lock <0x00000000d7d53cb8> (a java.lang.Object)
- locked <0x00000000d7d53ca8> (a java.lang.Object)
at ls.lock.Test$1.run(Test.java:15)
Found 1 deadlock.
Heap
PSYoungGen total 36352K, used 3751K [0x00000000d7c00000, 0x00000000da480000, 0x0000000100000000)
eden space 31232K, 12% used [0x00000000d7c00000,0x00000000d7fa9ce0,0x00000000d9a80000)
from space 5120K, 0% used [0x00000000d9f80000,0x00000000d9f80000,0x00000000da480000)
to space 5120K, 0% used [0x00000000d9a80000,0x00000000d9a80000,0x00000000d9f80000)
ParOldGen total 82432K, used 0K [0x0000000087400000, 0x000000008c480000, 0x00000000d7c00000)
object space 82432K, 0% used [0x0000000087400000,0x0000000087400000,0x000000008c480000)
PSPermGen total 21504K, used 3201K [0x0000000082200000, 0x0000000083700000, 0x0000000087400000)
object space 21504K, 14% used [0x0000000082200000,0x0000000082520540,0x0000000083700000)
参考:
https://blog.csdn.net/rachel_luo/article/details/8920596
https://www.javatang.com/archives/tag/%E5%86%85%E5%AD%98%E6%B3%84%E6%BC%8F
http://just2do.iteye.com/blog/2275894
https://www.javatang.com/archives/2017/10/19/33151873.html
https://dzone.com/articles/how-analyze-java-thread-dumps
https://www.cnblogs.com/zhengyun_ustc/archive/2013/01/06/dumpanalysis.html
https://blog.csdn.net/rachel_luo/article/details/8920596
http://jameswxx.iteye.com/blog/1041173
https://blog.csdn.net/wanyanxgf/article/details/6944987
https://blog.csdn.net/sprayabc/article/details/8509218
http://www.7dtest.com/site/article-80-1.html
https://blog.csdn.net/rachel_luo/article/details/8990202
https://blog.csdn.net/rachel_luo/article/details/8992461
http://planeteclipse.org/planet/
http://mindprod.com/jgloss/interned.html
http://mindprod.com/jgloss/weak.html
http://mindprod.com/jgloss/permgen.html
http://mindprod.com/jgloss/classloader.html
http://www.cnblogs.com/toSeeMyDream/p/7151635.html