死锁的示例代码:
public class MyTest4 {
public static void main(String[] args) {
new Thread(() -> A.method()).start();
new Thread(() -> B.method()).start();
}
}
class A {
public static synchronized void method() {
System.out.println("method from A");
try {
Thread.sleep(3000);//等待B获取锁
} catch (InterruptedException e) {
e.printStackTrace();
}
B.method();
}
}
class B {
public static synchronized void method() {
System.out.println("method from B");
try {
Thread.sleep(3000);//等待B获取锁
} catch (InterruptedException e) {
e.printStackTrace();
}
A.method();
}
}
通过jconsole来检测死锁:
名称: Thread-1
状态: java.lang.Class@1b3b48b5上的BLOCKED, 拥有者: Thread-0//可以看出来是类锁
总阻止数: 2, 总等待数: 1
堆栈跟踪:
com.compass.spring_lecture.memory.A.method(MyTest4.java:22)
com.compass.spring_lecture.memory.B.method(MyTest4.java:47)
- 已锁定 java.lang.Class@7bf00c13
com.compass.spring_lecture.memory.MyTest4.lambda1(MyTest4.java:11)
com.compass.spring_lecture.memory.MyTest4$$Lambda$2/780237624.run(Unknown Source)
java.lang.Thread.run(Thread.java:748)
名称: Thread-0
状态: java.lang.Class@7bf00c13上的BLOCKED, 拥有者: Thread-1
总阻止数: 1, 总等待数: 1
堆栈跟踪:
com.compass.spring_lecture.memory.B.method(MyTest4.java:40)
com.compass.spring_lecture.memory.A.method(MyTest4.java:30)
- 已锁定 java.lang.Class@1b3b48b5
com.compass.spring_lecture.memory.MyTest4.lambda0(MyTest4.java:9)
com.compass.spring_lecture.memory.MyTest4$$Lambda$1/521645586.run(Unknown Source)
java.lang.Thread.run(Thread.java:748)
使用jvisualvm来检测死锁:
使用线程dump来观察结果:
"Thread-1" #12 prio=5 os_prio=0 tid=0x000000001c1d8800 nid=0x3074 waiting for monitor entry [0x000000001cb1f000]
java.lang.Thread.State: BLOCKED (on object monitor)
at com.compass.spring_lecture.memory.A.method(MyTest4.java:22)
- waiting to lock <0x0000000784993970> (a java.lang.Class for com.compass.spring_lecture.memory.A)
at com.compass.spring_lecture.memory.B.method(MyTest4.java:47)
- locked <0x0000000784993328> (a java.lang.Class for com.compass.spring_lecture.memory.B)
at com.compass.spring_lecture.memory.MyTest4.lambda1(MyTest4.java:11)
at com.compass.spring_lecture.memory.MyTest4$$Lambda$2/780237624.run(Unknown Source)
at java.lang.Thread.run(Thread.java:748)
Locked ownable synchronizers:
- None
"Thread-0" #11 prio=5 os_prio=0 tid=0x000000001c1d8000 nid=0x4528 waiting for monitor entry [0x000000001c9be000]
java.lang.Thread.State: BLOCKED (on object monitor)
at com.compass.spring_lecture.memory.B.method(MyTest4.java:40)
- waiting to lock <0x0000000784993328> (a java.lang.Class for com.compass.spring_lecture.memory.B)
at com.compass.spring_lecture.memory.A.method(MyTest4.java:30)
- locked <0x0000000784993970> (a java.lang.Class for com.compass.spring_lecture.memory.A)
at com.compass.spring_lecture.memory.MyTest4.lambda0(MyTest4.java:9)
at com.compass.spring_lecture.memory.MyTest4$$Lambda$1/521645586.run(Unknown Source)
at java.lang.Thread.run(Thread.java:748)
Locked ownable synchronizers:
- None
Found one Java-level deadlock:
"Thread-1":
waiting to lock monitor 0x0000000019bb1c28 (object 0x0000000784993970, a java.lang.Class),
which is held by "Thread-0"
"Thread-0":
waiting to lock monitor 0x0000000019bb4618 (object 0x0000000784993328, a java.lang.Class),
which is held by "Thread-1"