什么是线程死锁
简介:死锁就是指两个以上(线程)在执行的过程之间,由于线程之间的通信或者资源竞争造成的一种阻塞现象。若没有其他助力情况下面,他们都无法继续执行,那么此时就称系统产生了死锁
就如下图所示,线程 A 持有资源 b,线程 B 持有资源 a,他们同时都想申请对方的资源,所以这两个线程就会互相等待而进入死锁状态。
模
型
\color{#FF0000}{模型}
模型
实例
package ThreadDemo;
/**
* Created by jdx on 2021/12/31 上午8:57
*/
public class DeadLock {
private static Object res01 = new Object();//资源 1
private static Object res02 = new Object();//资源 2
public static void main(String[] args) {
//使用lombok语法对资源一进行加锁,然后在控制台输出
new Thread(() -> {
synchronized (res01) {
System.out.println(Thread.currentThread() + "获得 res01");
try {
//线程休眠
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread() + "waiting get res02");
//给线程加锁并在控制台输出获得线程02的信息
synchronized (res02) {
System.out.println(Thread.currentThread() + "获得 res02");
}
}
}, "线程 01").start();
new Thread(() -> {
synchronized (res02) {
System.out.println(Thread.currentThread() + "获得 res02");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread() + "waiting get res01");
synchronized (res01) {
System.out.println(Thread.currentThread() + "获得 res01");
}
}
}, "线程 02").start();
}
}
输出结果为
Thread[线程 01,5,main]获得 res01
Thread[线程 02,5,main]获得 res02
Thread[线程 01,5,main]waiting get res02
Thread[线程 02,5,main]waiting get res01
那我现在来说明一下上述代码整体思路:线程 A 通过 synchronized (res01) 获得 res01 的监视器锁,然后通过Thread.sleep(1000);让线程 A 休眠 1s 为的是让线程 B 得到CPU执行权,然后获取到 res02 的监视器锁。线程 A 和线程 B 休眠结束了都开始企图请求获取对方的资源,然后这两个线程就会陷入互相等待的状态,这也就产生了死锁。
解决死锁的方案
那么既然明白了死锁产生的原因,那么我们在实战中是否就会对其产生预防呢?
- 破坏循环等待条件
靠按序申请资源来预防,破坏循环等待条件。
- 破坏请求与保持条件
一次性申请所有的资源。
- 破坏不剥夺条件
占用部分资源的线程进一步申请其他资源时,如果线程申请不到,那么我们主动释放它占有的资源。