死锁的理解

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

样例:有两个化妆使用的口红和镜子资源,两个女生使用。构造死锁场景,小红拿到了口红,小白拿到了镜子。此时她们两个都想再拿对方的资源,但是都没有释放自己手中的资源导致死锁。
代码:

package com.nqboot.boot.thread.syn.deeadLock;

public class DeadLock {
    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();

    // 表示选择哪一个器材,0代表口红。1代表镜子
    int choice;
    // 使用的人
    String girlName;

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

    @Override
    public void run() {
        //化妆
        try {
            makeup();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }

    private void makeup() throws InterruptedException {
        if (choice == 0) {
            synchronized (lipstick) {//获得口红资源
                System.out.println(this.girlName + "获得口红资源的锁");
                Thread.sleep(1000); // 1s后想获得镜子的锁
                synchronized (mirror) {
                    System.out.println(this.girlName + "获得镜子资源的锁");
                }
            }

        } else {
            synchronized (mirror) {//获得口红资源
                System.out.println(this.girlName + "获得镜子资源的锁");
                Thread.sleep(2000); // 2s后想获得口红的锁
                synchronized (lipstick) {
                    System.out.println(this.girlName + "获得口红资源的锁");
                }
            }
        }
    }

}

输出:

G:\Java\jdk1.8.0_191\bin\java.exe "-javaagent:G:\Intellij_IDEA\IntelliJ IDEA Community Edition 2022.2.3\lib\idea_rt.jar=53104:G:\Intellij_IDEA\IntelliJ IDEA Community Edition 2022.2.3\bin" -Dfile.encoding=UTF-8 -classpath G:\java\jdk1.8.0_191\jre\lib\charsets.jar;G:\java\jdk1.8.0_191\jre\lib\deploy.jar;G:\java\jdk1.8.0_191\jre\lib\ext\access-bridge-64.jar;G:\java\jdk1.8.0_191\jre\lib\ext\cldrdata.jar;G:\java\jdk1.8.0_191\jre\lib\ext\dnsns.jar;G:\java\jdk1.8.0_191\jre\lib\ext\jaccess.jar;G:\java\jdk1.8.0_191\jre\lib\ext\jfxrt.jar;G:\java\jdk1.8.0_191\jre\lib\ext\localedata.jar;G:\java\jdk1.8.0_191\jre\lib\ext\nashorn.jar;G:\java\jdk1.8.0_191\jre\lib\ext\sunec.jar;G:\java\jdk1.8.0_191\jre\lib\ext\sunjce_provider.jar;G:\java\jdk1.8.0_191\jre\lib\ext\sunmscapi.jar;G:\java\jdk1.8.0_191\jre\lib\ext\sunpkcs11.jar;G:\java\jdk1.8.0_191\jre\lib\ext\zipfs.jar;G:\java\jdk1.8.0_191\jre\lib\javaws.jar;G:\java\jdk1.8.0_191\jre\lib\jce.jar;G:\java\jdk1.8.0_191\jre\lib\jfr.jar;G:\java\jdk1.8.0_191\jre\lib\jfxswt.jar;G:\java\jdk1.8.0_191\jre\lib\jsse.jar;G:\java\jdk1.8.0_191\jre\lib\management-agent.jar;G:\java\jdk1.8.0_191\jre\lib\plugin.jar;G:\java\jdk1.8.0_191\jre\lib\resources.jar;G:\java\jdk1.8.0_191\jre\lib\rt.jar;D:\JavaLearning\springBootStudy\boot\target\classes;D:\repository\org\springframework\boot\spring-boot-starter-web\2.7.12\spring-boot-starter-web-2.7.12.jar;D:\repository\org\springframework\boot\spring-boot-starter\2.7.12\spring-boot-starter-2.7.12.jar;D:\repository\org\springframework\boot\spring-boot\2.7.12\spring-boot-2.7.12.jar;D:\repository\org\springframework\boot\spring-boot-autoconfigure\2.7.12\spring-boot-autoconfigure-2.7.12.jar;D:\repository\org\springframework\boot\spring-boot-starter-logging\2.7.12\spring-boot-starter-logging-2.7.12.jar;D:\repository\ch\qos\logback\logback-classic\1.2.12\logback-classic-1.2.12.jar;D:\repository\ch\qos\logback\logback-core\1.2.12\logback-core-1.2.12.jar;D:\repository\org\apache\logging\log4j\log4j-to-slf4j\2.17.2\log4j-to-slf4j-2.17.2.jar;D:\repository\org\apache\logging\log4j\log4j-api\2.17.2\log4j-api-2.17.2.jar;D:\repository\org\slf4j\jul-to-slf4j\1.7.36\jul-to-slf4j-1.7.36.jar;D:\repository\jakarta\annotation\jakarta.annotation-api\1.3.5\jakarta.annotation-api-1.3.5.jar;D:\repository\org\yaml\snakeyaml\1.30\snakeyaml-1.30.jar;D:\repository\org\springframework\boot\spring-boot-starter-json\2.7.12\spring-boot-starter-json-2.7.12.jar;D:\repository\com\fasterxml\jackson\core\jackson-databind\2.13.5\jackson-databind-2.13.5.jar;D:\repository\com\fasterxml\jackson\core\jackson-annotations\2.13.5\jackson-annotations-2.13.5.jar;D:\repository\com\fasterxml\jackson\core\jackson-core\2.13.5\jackson-core-2.13.5.jar;D:\repository\com\fasterxml\jackson\datatype\jackson-datatype-jdk8\2.13.5\jackson-datatype-jdk8-2.13.5.jar;D:\repository\com\fasterxml\jackson\datatype\jackson-datatype-jsr310\2.13.5\jackson-datatype-jsr310-2.13.5.jar;D:\repository\com\fasterxml\jackson\module\jackson-module-parameter-names\2.13.5\jackson-module-parameter-names-2.13.5.jar;D:\repository\org\springframework\boot\spring-boot-starter-tomcat\2.7.12\spring-boot-starter-tomcat-2.7.12.jar;D:\repository\org\apache\tomcat\embed\tomcat-embed-core\9.0.75\tomcat-embed-core-9.0.75.jar;D:\repository\org\apache\tomcat\embed\tomcat-embed-el\9.0.75\tomcat-embed-el-9.0.75.jar;D:\repository\org\apache\tomcat\embed\tomcat-embed-websocket\9.0.75\tomcat-embed-websocket-9.0.75.jar;D:\repository\org\springframework\spring-web\5.3.27\spring-web-5.3.27.jar;D:\repository\org\springframework\spring-beans\5.3.27\spring-beans-5.3.27.jar;D:\repository\org\springframework\spring-webmvc\5.3.27\spring-webmvc-5.3.27.jar;D:\repository\org\springframework\spring-aop\5.3.27\spring-aop-5.3.27.jar;D:\repository\org\springframework\spring-context\5.3.27\spring-context-5.3.27.jar;D:\repository\org\springframework\spring-expression\5.3.27\spring-expression-5.3.27.jar;D:\repository\org\projectlombok\lombok\1.18.26\lombok-1.18.26.jar;D:\repository\org\slf4j\slf4j-api\1.7.36\slf4j-api-1.7.36.jar;D:\repository\org\springframework\spring-core\5.3.27\spring-core-5.3.27.jar;D:\repository\org\springframework\spring-jcl\5.3.27\spring-jcl-5.3.27.jar;D:\repository\org\testng\testng\6.14.3\testng-6.14.3.jar;D:\repository\com\beust\jcommander\1.72\jcommander-1.72.jar;D:\repository\org\apache-extras\beanshell\bsh\2.0b6\bsh-2.0b6.jar;D:\repository\commons-io\commons-io\2.8.0\commons-io-2.8.0.jar com.nqboot.boot.thread.syn.deeadLock.DeadLock
小红获得口红资源的锁
小白获得镜子资源的锁

解决方案:当需要拿其他人使用的共享资源时,先把自己手中的资源释放再去拿,避免死锁发生。

代码:

package com.nqboot.boot.thread.syn.deeadLock;

public class DeadLock {
    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();

    // 表示选择哪一个器材,0代表口红。1代表镜子
    int choice;
    // 使用的人
    String girlName;

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

    @Override
    public void run() {
        //化妆
        try {
            makeup();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }

    private void makeup() throws InterruptedException {
        if (choice == 0) {
            synchronized (lipstick) {//获得口红资源
                System.out.println(this.girlName + "获得口红资源的锁");
                Thread.sleep(1000);
            }
            synchronized (mirror) {// 1s后想获得镜子的锁
                System.out.println(this.girlName + "获得镜子资源的锁");
            }

        } else {
            synchronized (mirror) {//获得口红资源
                System.out.println(this.girlName + "获得镜子资源的锁");
                Thread.sleep(2000);
            }
            synchronized (lipstick) {// 2s后想获得口红的锁
                System.out.println(this.girlName + "获得口红资源的锁");
            }
        }
    }

}

输出:

G:\Java\jdk1.8.0_191\bin\java.exe "-javaagent:G:\Intellij_IDEA\IntelliJ IDEA Community Edition 2022.2.3\lib\idea_rt.jar=53274:G:\Intellij_IDEA\IntelliJ IDEA Community Edition 2022.2.3\bin" -Dfile.encoding=UTF-8 -classpath G:\java\jdk1.8.0_191\jre\lib\charsets.jar;G:\java\jdk1.8.0_191\jre\lib\deploy.jar;G:\java\jdk1.8.0_191\jre\lib\ext\access-bridge-64.jar;G:\java\jdk1.8.0_191\jre\lib\ext\cldrdata.jar;G:\java\jdk1.8.0_191\jre\lib\ext\dnsns.jar;G:\java\jdk1.8.0_191\jre\lib\ext\jaccess.jar;G:\java\jdk1.8.0_191\jre\lib\ext\jfxrt.jar;G:\java\jdk1.8.0_191\jre\lib\ext\localedata.jar;G:\java\jdk1.8.0_191\jre\lib\ext\nashorn.jar;G:\java\jdk1.8.0_191\jre\lib\ext\sunec.jar;G:\java\jdk1.8.0_191\jre\lib\ext\sunjce_provider.jar;G:\java\jdk1.8.0_191\jre\lib\ext\sunmscapi.jar;G:\java\jdk1.8.0_191\jre\lib\ext\sunpkcs11.jar;G:\java\jdk1.8.0_191\jre\lib\ext\zipfs.jar;G:\java\jdk1.8.0_191\jre\lib\javaws.jar;G:\java\jdk1.8.0_191\jre\lib\jce.jar;G:\java\jdk1.8.0_191\jre\lib\jfr.jar;G:\java\jdk1.8.0_191\jre\lib\jfxswt.jar;G:\java\jdk1.8.0_191\jre\lib\jsse.jar;G:\java\jdk1.8.0_191\jre\lib\management-agent.jar;G:\java\jdk1.8.0_191\jre\lib\plugin.jar;G:\java\jdk1.8.0_191\jre\lib\resources.jar;G:\java\jdk1.8.0_191\jre\lib\rt.jar;D:\JavaLearning\springBootStudy\boot\target\classes;D:\repository\org\springframework\boot\spring-boot-starter-web\2.7.12\spring-boot-starter-web-2.7.12.jar;D:\repository\org\springframework\boot\spring-boot-starter\2.7.12\spring-boot-starter-2.7.12.jar;D:\repository\org\springframework\boot\spring-boot\2.7.12\spring-boot-2.7.12.jar;D:\repository\org\springframework\boot\spring-boot-autoconfigure\2.7.12\spring-boot-autoconfigure-2.7.12.jar;D:\repository\org\springframework\boot\spring-boot-starter-logging\2.7.12\spring-boot-starter-logging-2.7.12.jar;D:\repository\ch\qos\logback\logback-classic\1.2.12\logback-classic-1.2.12.jar;D:\repository\ch\qos\logback\logback-core\1.2.12\logback-core-1.2.12.jar;D:\repository\org\apache\logging\log4j\log4j-to-slf4j\2.17.2\log4j-to-slf4j-2.17.2.jar;D:\repository\org\apache\logging\log4j\log4j-api\2.17.2\log4j-api-2.17.2.jar;D:\repository\org\slf4j\jul-to-slf4j\1.7.36\jul-to-slf4j-1.7.36.jar;D:\repository\jakarta\annotation\jakarta.annotation-api\1.3.5\jakarta.annotation-api-1.3.5.jar;D:\repository\org\yaml\snakeyaml\1.30\snakeyaml-1.30.jar;D:\repository\org\springframework\boot\spring-boot-starter-json\2.7.12\spring-boot-starter-json-2.7.12.jar;D:\repository\com\fasterxml\jackson\core\jackson-databind\2.13.5\jackson-databind-2.13.5.jar;D:\repository\com\fasterxml\jackson\core\jackson-annotations\2.13.5\jackson-annotations-2.13.5.jar;D:\repository\com\fasterxml\jackson\core\jackson-core\2.13.5\jackson-core-2.13.5.jar;D:\repository\com\fasterxml\jackson\datatype\jackson-datatype-jdk8\2.13.5\jackson-datatype-jdk8-2.13.5.jar;D:\repository\com\fasterxml\jackson\datatype\jackson-datatype-jsr310\2.13.5\jackson-datatype-jsr310-2.13.5.jar;D:\repository\com\fasterxml\jackson\module\jackson-module-parameter-names\2.13.5\jackson-module-parameter-names-2.13.5.jar;D:\repository\org\springframework\boot\spring-boot-starter-tomcat\2.7.12\spring-boot-starter-tomcat-2.7.12.jar;D:\repository\org\apache\tomcat\embed\tomcat-embed-core\9.0.75\tomcat-embed-core-9.0.75.jar;D:\repository\org\apache\tomcat\embed\tomcat-embed-el\9.0.75\tomcat-embed-el-9.0.75.jar;D:\repository\org\apache\tomcat\embed\tomcat-embed-websocket\9.0.75\tomcat-embed-websocket-9.0.75.jar;D:\repository\org\springframework\spring-web\5.3.27\spring-web-5.3.27.jar;D:\repository\org\springframework\spring-beans\5.3.27\spring-beans-5.3.27.jar;D:\repository\org\springframework\spring-webmvc\5.3.27\spring-webmvc-5.3.27.jar;D:\repository\org\springframework\spring-aop\5.3.27\spring-aop-5.3.27.jar;D:\repository\org\springframework\spring-context\5.3.27\spring-context-5.3.27.jar;D:\repository\org\springframework\spring-expression\5.3.27\spring-expression-5.3.27.jar;D:\repository\org\projectlombok\lombok\1.18.26\lombok-1.18.26.jar;D:\repository\org\slf4j\slf4j-api\1.7.36\slf4j-api-1.7.36.jar;D:\repository\org\springframework\spring-core\5.3.27\spring-core-5.3.27.jar;D:\repository\org\springframework\spring-jcl\5.3.27\spring-jcl-5.3.27.jar;D:\repository\org\testng\testng\6.14.3\testng-6.14.3.jar;D:\repository\com\beust\jcommander\1.72\jcommander-1.72.jar;D:\repository\org\apache-extras\beanshell\bsh\2.0b6\bsh-2.0b6.jar;D:\repository\commons-io\commons-io\2.8.0\commons-io-2.8.0.jar com.nqboot.boot.thread.syn.deeadLock.DeadLock
小红获得口红资源的锁
小白获得镜子资源的锁
小白获得口红资源的锁
小红获得镜子资源的锁

Process finished with exit code 0

避免死锁的方法:
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值