引言
这个情况现象的程序运行的时候迟迟没有输出,我们可以怀疑的死锁的问题,但是怎么去定位这个问题呢,我们还是借助jstack来做。
jstack 163746
这个查看没有太复杂的流程,直接查看堆栈信息最后的一部分就ok
Found one Java-level deadlock:
=============================
"Thread_02":
waiting to lock monitor 0x00002b578c002178 (object 0x000000058015e5c0, a O1),
which is held by "Thread_01"
"Thread_01":
waiting to lock monitor 0x00002b578c006218 (object 0x000000058015f148, a O2),
which is held by "Thread_02"
Java stack information for the threads listed above:
===================================================
"Thread_02":
at Demo1_3.lambda$main$1(Demo1_3.java:28)
- waiting to lock <0x000000058015e5c0> (a O1)
- locked <0x000000058015f148> (a O2)
at Demo1_3$$Lambda$2/1418481495.run(Unknown Source)
at java.lang.Thread.run(Thread.java:745)
"Thread_01":
at Demo1_3.lambda$main$0(Demo1_3.java:17)
- waiting to lock <0x000000058015f148> (a O2)
- locked <0x000000058015e5c0> (a O1)
at Demo1_3$$Lambda$1/834600351.run(Unknown Source)
at java.lang.Thread.run(Thread.java:745)
Found 1 deadlock.
信息会很明确告诉有一个死锁,并且指明了代码行17行和28行,定位到这里就方便了,我们拿出源代码看看:
class O1{}
class O2{}
public class Demo1_3 {
static O1 o1=new O1();
static O2 o2=new O2();
public static void main(String[] args) throws InterruptedException {
new Thread(()->{
synchronized (o1){
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (o2){
System.out.println("我是线程1,我获得了o1和o2");
}
}
},"Thread_01").start();
Thread.sleep(1000);
new Thread(()->{
synchronized (o2){
synchronized (o1){
System.out.println("我是线程2,我获得了o1和o2");
}
}
},"Thread_02").start();
}
}
可以看到,线程1和2分别取锁定o1和o2,线程1在持有了o1的同时又准备去锁住o2,而线程2则先持有o2再去锁定o1,双方都没有释放,进而死锁了。