JAVA多线程——死锁DeadLock

JAVA多线程——死锁

死锁问题:多个线程互相拿着对方需要的资源,然后形成僵持
出现死锁后,不会出现异常,不会出现提示,只是所有的线程都处于阻塞状态,无法继续
死锁问题的演示

package com.work;

public class work6 {
    
    
    public static void main(String[] args) {
    
    
        StringBuffer s1 = new StringBuffer();
        StringBuffer s2 = new StringBuffer();


        //线程一
        new Thread(){
    
    //用匿名内部类的方式创建线程(继承Thread类)
            @Override
            public void run() {
    
    
                synchronized(s1){
    
    //线程一先获得s1的锁
                   s1.append("a");
                   s2.append(1);

                    try {
    
    
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
    
    
                        e.printStackTrace();
                    }
                    synchronized(s2){
    
    //再获得s2的锁
                       s1.append("b");
                       s2.append(2);
                       //线程一只有同时获得了s1和s2的锁才能输出s1,s2
                       System.out.println(s1);
                       System.out.println(s2);
                   }
                }

            }
        }.start();

        //线程二
    new Thread(new Runnable() {
    
    //实现Runnable接口
        @Override
        public void run() {
    
    
            synchronized (s2) {
    
    //线程二先获得s2的锁
                s1.append("c");
                s2.append(3);

                try {
    
    
                    Thread.sleep(100);
                } catch (InterruptedException e) {
    
    
                    e.printStackTrace();
                }

                synchronized (s1) {
    
    //再获得s1的锁
                    s1.append("d");
                    s2.append(4);

                    System.out.println(s1);
                    System.out.println(s2);
                }
            }

        }
    }).start();
}
}

案例二

package com.peng.demon06;

import com.sun.deploy.security.SelectableSecurityManager;

//死锁:多个线程互相拿着对方需要的资源,然后形成僵持
//案例背景:白雪公主,灰胡娘两个人都想化妆,但只有有个镜子和一个口红,然后一个人拿着口红,一个人拿着镜子,导致谁也化不了
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();

    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) {
    
    
            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){
    
    //2秒后还想获得口红的锁
                    System.out.println(this.girlName+"获得镜子的锁");
                }
            }

        }
    }



}

死锁导致程序卡死

在这里插入图片描述

解决方法:把两个同步块分开来放,不要放在一起不要让两个线程互相抱对方的锁

package com.peng.demon06;

import com.sun.deploy.security.SelectableSecurityManager;

//死锁:多个线程互相拿着对方需要的资源,然后形成僵持
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();

    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) {
    
    
            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){
    
    //2秒后还想获得口红的锁
                System.out.println(this.girlName+"获得口红的锁");
            }

        }
    }



}

在这里插入图片描述

产生死锁的四个必要条件

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

我们只要想办法破其中一种或多种条件就可以避免死锁的发生

猜你喜欢

转载自blog.csdn.net/wpc2018/article/details/108372153