死锁的介绍
目录
1.什么是死锁
死锁是指两个或者两个以上的进程(线程)在执行的过程中,由于竞争资源而造成的阻塞问题,若无外力的作用下会无法继续推进,此时系统称之为死锁状态
2.死锁的形成
如图所示:将设存在两个线程SetThread和GetThread,现在SetThread持有了ObjectA资源请求资源ObjectB。
GetThread持有了ObjectB资源请求资源ObjectA,ObjectA和ObjectB资源的获取是互斥的,两个线程等待另一个资源而不释放持有的资源,就会无限等待下去,这就是死锁。
3.死锁的原因
1.因进程资源产生死锁
2.进程推进顺序不当
4.死锁代码示例
public class DeadLockDemo {
private static Object obj1 = new Object();
private static Object obj2 = new Object();
public static void main(String[] args) {
//线程1先获取obj1在获取obj2
//线程2先获取obj2在获取obj1
Runnable t1 = new Runnable() {
@Override
public void run() {
synchronized (obj1) {
System.out.println("线程1获取到资源1");
synchronized (obj2) {
System.out.println("线程1获取资源2");
}
}
}
};
Runnable t2 = new Runnable() {
@Override
public void run() {
synchronized (obj2) {
System.out.println("线程2获取到资源2");
synchronized (obj1) {
System.out.println("线程2获取资源1");
}
}
}
};
//启动线程
new Thread(t1).start();
new Thread(t2).start();
}
}
5.产生死锁的四个必要条件
1.互斥条件:一个资源每次是能被一个线程使用
2.请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放
3.不可剥夺条件:进程已获得的资源,在未使用完成之前,不能强行剥夺
4.循环等待条件:若干进程之间形成一种首尾相连的循环等待资源的关系
6.死锁的解除与预防
解决死锁的三种途径:预防、避免、检测与恢复
1.死锁预防
预防死锁只需要破坏4个必要条件就可以
(1)资源的一次性分配:破坏请求与保持的
(2)可剥夺资源:当进程准备获取新资源为满足时,需要将已占有的资源释放掉(破坏不可剥夺条件)
(3)资源的有序分配法:系统对每个资源进行编号,每一个线程按照编号递增顺序请求资源,释放资源正好相反(破坏请求保持)
2.避免死锁(银行家算法)
避免死锁的策略中,允许进程进行资源的动态申请,系统在资源分配之前先进性预分配,先计算资源分配的安全性,不会导致系统进入到不安全的状态,系统会将资源真正的分配给进程,经典的避免死锁的方法就是银行家算法。
3.检测和解除死锁
当发现进程死锁后,立即从死锁状态解救处理啊,采用方式:
剥夺资源:从其他进程中剥夺足够多的资源给死锁进程,以避免死锁状态(MYSQL中死锁解决方案就是这个思路)
撤销进程:直接撤销死锁进程或者是撤销代价最小的进程,直至有足够资源可用时时才执行撤销线程
本人才疏学浅,如有错误,烦请指出,谢谢!