如何写一个死锁
用两个线程,两个对象,线程a锁住obj1然后再去锁obj2,线程b锁住obj2然后去锁obj1。这时候线程a持有obj1的锁,线程b持有obj2的锁,当等待时间结束,就会互相等待锁,形成死锁。
package com.example.mystudy.thread;
/**
* Created by Jan on 2022/7/8.
*/
public class TestDeadLock {
public static void main(String[] args) {
Object obj1 = new Object();
Object obj2 = new Object();
System.out.println("test start");
Thread lock_a = new Thread(() -> {
System.out.println(Thread.currentThread().getName() + ":start");
synchronized (obj1) {
System.out.println("lock obj1");
try {
Thread.sleep(1000);
synchronized (obj2) {
System.out.println("lock obj1->obj2");
}
} catch (InterruptedException ignored) {
}
}
});
Thread lock_b = new Thread(() -> {
System.out.println(Thread.currentThread().getName() + ":start");
synchronized (obj2) {
System.out.println("lock obj2");
try {
Thread.sleep(1000);
synchronized (obj1) {
System.out.println("lock obj2->obj1");
}
} catch (InterruptedException ignored) {
}
}
});
lock_a.start();
lock_b.start();
System.out.println("test end");
}
}
输出
test start
test end
Thread-1:start
lock obj2
Thread-0:start
lock obj1
查看死锁
~ jstack -h
Usage:
jstack [-l] <pid>
(to connect to running process)
Options:
-l long listing. Prints additional information about locks
-h or -help to print this help message
执行
jstack -l 32878
输出
Found one Java-level deadlock:
=============================
"Thread-1":
waiting to lock monitor 0x000000013a80daa0 (object 0x000000076ae31530, a java.lang.Object),
which is held by "Thread-0"
"Thread-0":
waiting to lock monitor 0x000000013a80b370 (object 0x000000076ae31540, a java.lang.Object),
which is held by "Thread-1"
Java stack information for the threads listed above:
===================================================
"Thread-1":
at com.example.mystudy.thread.TestDeadLock.lambda$main$1(TestDeadLock.java:31)
- waiting to lock <0x000000076ae31530> (a java.lang.Object)
- locked <0x000000076ae31540> (a java.lang.Object)
at com.example.mystudy.thread.TestDeadLock$$Lambda$2/1826771953.run(Unknown Source)
at java.lang.Thread.run(Thread.java:750)
"Thread-0":
at com.example.mystudy.thread.TestDeadLock.lambda$main$0(TestDeadLock.java:18)
- waiting to lock <0x000000076ae31540> (a java.lang.Object)
- locked <0x000000076ae31530> (a java.lang.Object)
at com.example.mystudy.thread.TestDeadLock$$Lambda$1/142257191.run(Unknown Source)
at java.lang.Thread.run(Thread.java:750)
Found 1 deadlock.
输出分析:
可以看到有一个deadlock,线程信息Thread-1锁住了0x000000076ae31540,等待0x000000076ae31530的锁,而线程Thread-0 锁住 <0x000000076ae31530>,等待0x000000076ae31540的锁,相互等待对方释放锁。
另外也可以使用jconsole查看,这是一个可视化界面。
选择“线程”,里面有一项叫死锁检测,这个更加的直观。