死锁以及避免方法

2020-11-16  本文已影响0人  i小雨

概念:

死锁的例子:(化妆)

package com.company.ThreadTest;

//死锁
public class TestDeadLock {
    public static void main(String[] args) {

        Makeup g1 = new Makeup(0,"灰姑娘");
        Makeup g2 = new Makeup(1,"白雪公主");

        g1.start();
        g2.start();
    }
}

//口红
class Lipstick{

}
//镜子
class Mirror{

}
class Makeup extends Thread{
    //需要的资源只有一份,用static来保证只有一份
    static Lipstick lipstick = new Lipstick();
    static Mirror mirror = new Mirror();

    int choice;//选择
    String name;//人

    Makeup(int choice,String name){
        this.choice = choice;
        this.name = name;
    }

    @Override
    public void run() {
        //化妆
        try {
            makeup();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    //化妆方法,互相持有对方的锁。
    private void makeup() throws InterruptedException {
        if (choice==0){
            synchronized (lipstick){ //获得口红的锁
                System.out.println(this.name+"获得口红的锁");
                Thread.sleep(1000);

                synchronized (mirror){ //1秒钟后想获得镜子的锁
                    System.out.println(this.name+"获得镜子的锁");
                }
            }
        }else {
            synchronized (mirror){ //获得镜子的锁
                System.out.println(this.name+"获得镜子的锁");
                Thread.sleep(2000);

                synchronized (lipstick){ //2秒钟后想获得口红的锁
                    System.out.println(this.name+"获得口红的锁");
                }
            }
        }
    }
}

结果:形成死锁

灰姑娘获得口红的锁
白雪公主获得镜子的锁

避免死锁的四个必要条件:

  1. 互斥条件:一个资源每次只能被一个进程使用。
  2. 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
  3. 不剥夺条件:进程已获得的资源,在未使用完之前,不能强行剥夺。
  4. 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。

上面是死锁发生的四个必要条件,我们只要破坏其中的任意一个或多个条件就可以避免死锁的发生。

化妆例子的改进:

package com.company.ThreadTest;

//死锁
public class TestDeadLock {
    public static void main(String[] args) {

        Makeup g1 = new Makeup(0,"灰姑娘");
        Makeup g2 = new Makeup(1,"白雪公主");

        g1.start();
        g2.start();
    }
}

//口红
class Lipstick{

}
//镜子
class Mirror{

}
class Makeup extends Thread{
    //需要的资源只有一份,用static来保证只有一份
    static Lipstick lipstick = new Lipstick();
    static Mirror mirror = new Mirror();

    int choice;//选择
    String name;//人

    Makeup(int choice,String name){
        this.choice = choice;
        this.name = name;
    }

    @Override
    public void run() {
        //化妆
        try {
            makeup();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    //化妆方法
    private void makeup() throws InterruptedException {
        if (choice==0){
            synchronized (lipstick){ //获得口红的锁
                System.out.println(this.name+"获得口红的锁");
                Thread.sleep(1000);

            }

            synchronized (mirror){ //1秒钟后想获得镜子的锁
                System.out.println(this.name+"获得镜子的锁");
            }
        }else {
            synchronized (mirror){ //获得镜子的锁
                System.out.println(this.name+"获得镜子的锁");
                Thread.sleep(2000);

            }

            synchronized (lipstick){ //2秒钟后想获得口红的锁
                System.out.println(this.name+"获得口红的锁");
            }
        }
    }
}

结果:

灰姑娘获得口红的锁
白雪公主获得镜子的锁
灰姑娘获得镜子的锁
白雪公主获得口红的锁
上一篇 下一篇

猜你喜欢

热点阅读