【狂神说Java】死锁

  • 多个线程各自占有一些共享资源,并且互相等待其他线程占有的资源才能运行,而导致两个或者多个线程都在等待对方释放资源,都停止执行的情形。
  • 某一个同步块同时拥有“两个以上对象的锁”,就可能发生“死锁”的问题。

死锁的四个必要条件

  • 互斥条件:一个资源每次只能被一个进程使用
  • 请求与保持条件:一个进程因请求资源阻塞时,对已获得的资源保持不放。
  • 不剥夺条件:进程已获得资源,在未使用完成前,不能强行剥夺。
  • 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。
public class DeadLock {
    public static void main(String[] args) {
        Makeup makeup1 = new Makeup(0,"test1");
        Makeup makeup2 = new Makeup(1,"test2");
        new Thread(makeup1).start();
        new Thread(makeup2).start();
    }
}

class Lipstick {

}

class Mirror {

}

class Makeup implements Runnable {
    static Lipstick lipstick = new Lipstick();
    static Mirror mirror = new Mirror();

    int choice;
    String girlName;

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

    @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.girlName + "口红锁");//获得口红的锁
                Thread.sleep(1000);
                synchronized (mirror) {
                    System.out.println(this.girlName + "镜子锁");//获得镜子的锁
                }// 释放镜子的锁
            }// 释放口红的锁
        } else {
            synchronized (mirror) {
                System.out.println(this.girlName + "镜子锁");//获得镜子的锁
                Thread.sleep(2000);
                synchronized (lipstick) {
                    System.out.println(this.girlName + "口红锁");//获得口红的锁
                }// 释放口红的锁
            }// 释放镜子的锁
        }
    }
}

这里死锁的解决方法:让一个同步块中只有一个对象的锁

    private void makeup() throws InterruptedException {
        if (choice == 0) {
            synchronized (lipstick) {
                System.out.println(this.girlName + "口红锁");//获得口红的锁
                Thread.sleep(1000);
            }// 释放口红的锁
            synchronized (mirror) {
                System.out.println(this.girlName + "镜子锁");//获得镜子的锁
            }// 释放镜子的锁
        } else {
            synchronized (mirror) {
                System.out.println(this.girlName + "镜子锁");//获得镜子的锁
                Thread.sleep(2000);
                }// 释放镜子的锁
            synchronized (lipstick) {
                System.out.println(this.girlName + "口红锁");//获得口红的锁
            }// 释放口红的锁
        }
    }
posted @ 2021-09-22 11:08  Jie7  阅读(61)  评论(0)    收藏  举报