死锁的根本原因

死锁的根本原因

  • 出现死锁要满足的条件
  • 预防死锁

出现死锁要满足的条件

1、互斥使用:即当资源被一个线程使用时,别的线程不能使用
2、 不可抢占:资源求生者不能强制从资源占有者手中夺取资源
3、占有且等待:占有且等待即当资源请求其他资源的同时,保持对原有资源的占有
4、 循环等待:循环等待即线程一等待线程二占有的资源,而线程二要等待的线程一占用的资源形成一个环路

死锁只有当这四个条件都发生时才可能出现,也就是说只要对其中一个条件进行破坏就能预防死锁,一般我们都不会对互斥条件进行破坏,因为某些资源就只能一个人使用,不能同时多人使用,像实现中的打印机,所有我们对其他三个条件进行破坏

预防死锁

1、破坏占有且等待:(包括占有前等待)每一个请求的一次性申请所有需要的资源,如果无法一次性申请所有资源,那就进行等待
死锁的根本原因_第1张图片

2、破坏不可抢占:当某个线程拿到一部分资源之后要去申请另一个资源时,如果申请不到,就主动释放它占有的所有资源
死锁的根本原因_第2张图片

3、破坏循环等待:采用资源有序分配其基本思想是将系统中的所有资源顺序编号,将紧缺的,稀少的采用较大的编号,在申请资源时必须按照编号的顺序进行,一个进程只有获得较小编号的进程才能申请较大编号的进程。
死锁的根本原因_第3张图片

演示死锁

public class Deadlock {
    public static void main(String[] args) {
        Object a = new Object();	//A资源
        Object b = new Object();	//B资源
        new Thread(()->{
            synchronized (a){
                System.out.println(Thread.currentThread().getName()+"i get a");
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName()+"i want b");
                synchronized (b){
                    System.out.println(Thread.currentThread().getName()+"i get b");
                }
            }
        }).start();

        new Thread(()->{
            synchronized (b){
                System.out.println(Thread.currentThread().getName()+"i get b");
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName()+"i want a");
                synchronized (a){
                    System.out.println(Thread.currentThread().getName()+"i get a");
                }
            }
        }).start();
    }
}

死锁的根本原因_第4张图片

安全状态: https://blog.csdn.net/jyy305/article/details/70077042.

你可能感兴趣的:(死锁的根本原因)