【笔记】手写死锁

死锁:多个线程互相持有对方所需要的资源,导致这些线程处于等待状态。

死锁产生的必要条件:

  • 互斥:一个资源只允许一个线程访问
  • 占有且等待:一个线程占有资源,同时还有其他线程未得到满足,正在等待其他线程释放该资源
  • 不可抢占:其他线程已经占有了某项资源,不能因为你需要就抢过来
  • 循环等待:发生死锁时,所等待的线程必定会形成一个环路,造成永久拥塞

通俗说法:

比如A和B两个人,一个厕所坑位,一卷卫生纸,A进厕所蹲坑去了,即A占有了坑,但是A没拿卫生纸,B拿了卫生纸后,B也想上厕所了,发现坑位有人了,那在门外等候,A占有了坑位,B占有了纸,A想得到纸,但是发现被B占了,都他妈没纸,怎么出来,B想上厕所,发现厕所被A占了,那他妈的怎么办,最后形成了僵持局面,A拿不到纸就占着坑不出去,B进不去坑我就拿着纸,然后两个就这样一直僵持着,形成了死锁。

造成死锁的原因通俗的概括成:

  • 当前线程拥有其他线程需要的资源
  • 当前线程等待其他线程已拥有的资源
  • 都不放弃自己拥有的资源

手写一个简单的死锁

public class DeadLock {
    private final Object left=new Object();
    private final Object right=new Object();

    public void leftToRight(){
        synchronized (left){
            try {
                Thread.sleep(100);
            }catch (InterruptedException e){
                e.printStackTrace();
            }
            synchronized (right){
                System.out.println("得到right");
            }
        }
    }

    public void rightToLeft(){
        synchronized (right){
            try {
                Thread.sleep(100);
            }catch (InterruptedException e){
                e.printStackTrace();
            }
            synchronized (left){
                System.out.println("得到left");
            }
        }
    }

    public static void main(String[] args) {
        DeadLock deadLock=new DeadLock();
        new Thread(new Runnable() {
            @Override
            public void run() {
                while(true){
                    deadLock.leftToRight();
                }
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                while(true){
                    deadLock.rightToLeft();
                }
            }
        }).start();
    }
}

死锁预防

互斥条件是必须的,不能被改变,还应该加以保证

  1. 破坏“占有且等待”
    • 所有线程在开始运行之前,必须一次性的申请在整个运行过程中所需要的全部资源
    • 允许线程只获取运行初期需要的资源,在运行过程中逐步的释放使用完毕的资源
  2. 破坏“不可抢占条件”
    • 当一个已经持有了一些资源的线程在提出新的资源请求没有得到满足时,它必须释放掉已经保持的所有资源
  3. 破坏“循环等待”
    • 定义资源类型的线性顺序来预防

避免死锁的方法

  • 固定加锁顺序
  • 开放调用
  • 使用定时锁
  • 死锁检测

原文链接:https://blog.csdn.net/pengbo6665631/article/details/86692912