我们先来创造一个死锁的情况,代码如下:
public class DeadLockDemo {
static Object resource1 = new Object();
static Object resource2 = new Object();
public static void main(String[] args) throws InterruptedException {
new Thread(()->{
synchronized (resource1) {
try {
System.out.println(Thread.currentThread() + "get resource1");
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread() + "ready to get resource2");
synchronized (resource2) {
System.out.println(Thread.currentThread() + "get resource2");
}
}
}).start();
new Thread(()->{
synchronized (resource2) {
System.out.println(Thread.currentThread() + "get resource2");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread() + "ready to get resource1");
synchronized (resource1) {
System.out.println(Thread.currentThread() + "get resource1");
}
}
}).start();
Thread.sleep(2000);
}
}
当程序运行之后,程序会卡住,两个线程相互争夺资源造成死锁:
输出如下:
Thread[Thread-0,5,main]get resource1
Thread[Thread-1,5,main]get resource2
Thread[Thread-0,5,main]ready to get resource2
Thread[Thread-1,5,main]ready to get resource1
我们打开shell,键入
C:\Users\Administrator>jps
1096
12252 DeadLockDemo
13964 Jps
6604 Launcher
可以发现正在运行中的DeadLockDemo的pid为12252
我们继续键入:
C:\Users\Administrator>jstack 12252
2021-03-22 23:49:15
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.261-b12 mixed mode):
"DestroyJavaVM" #14 prio=5 os_prio=0 tid=0x000001ffd2196000 nid=0x1bec waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Thread-1" #13 prio=5 os_prio=0 tid=0x000001ffd2197000 nid=0x2f30 waiting for monitor entry [0x000000b42ecff000]
java.lang.Thread.State: BLOCKED (on object monitor)
at DeadLockDemo.lambda$main$1(DeadLockDemo.java:34)
- waiting to lock <0x000000076b6b07f0> (a java.lang.Object)
- locked <0x000000076b6b0800> (a java.lang.Object)
at DeadLockDemo$$Lambda$2/2093631819.run(Unknown Source)
at java.lang.Thread.run(Thread.java:748)
"Thread-0" #12 prio=5 os_prio=0 tid=0x000001ffd219c000 nid=0x92c waiting for monitor entry [0x000000b42ebff000]
java.lang.Thread.State: BLOCKED (on object monitor)
at DeadLockDemo.lambda$main$0(DeadLockDemo.java:20)
- waiting to lock <0x000000076b6b0800> (a java.lang.Object)
- locked <0x000000076b6b07f0> (a java.lang.Object)
at DeadLockDemo$$Lambda$1/1023892928.run(Unknown Source)
at java.lang.Thread.run(Thread.java:748)
我们关注重点
waiting for monitor entry
我们知道synchronzied的底层原理使用的就是monitor,通过打印stack信息我们知道此时两个线程在分别阻塞等待获取monitor。我们观察代码可以知道,此时两个线程没有任何一方满足退出死锁的条件,且它们永远不会满足,因此可以推断,死锁将会持续发生。
这便是死锁的简单实战。