多线程-死锁


多个线程各自占有一些共享资源,并且互相等待其他线程占有的资源才能运行,而导致两个或者多个线程都在等待对方释放资源
都停止执行的情形,某一个同步块同时 拥有”两个以上对象的锁“时,就可能发生死锁的问题
//死锁:多个线程互相抱着对方需要的资源,然后形成僵持
public class Main {
    public static void main(String[] args) {
        //0,为口红,1为镜子
        Makeuo g1=new Makeuo(0,"小红帽");//第一个人
        Makeuo g2=new Makeuo(1,"灰姑娘");//第二个人
        //启动这两个线程
        g1.start();
        g2.start();
        
        
    }
}

//口红
class Lipatic{
    
}

//镜子
class Mirrot{
}

//化妆
class Makeuo extends Thread{
    //需要的资源只有一份,用static来保证只有份
    static Lipatic lip=new Lipatic();//创建一个口红对象
    static Mirrot mir=new Mirrot();//创建一个镜子对象
    
    int choice;//选择
    String girLnmae;//使用化妆品的人
    //构造器
    Makeuo(int choice,String girLnmae){
        this.choice=choice;
        this.girLnmae=girLnmae;
    }
    public void run(){
        //化妆
        makeup();
        
    }
    
    //化妆方法,互相持有对方的锁,就是需要拿到对方的 
    private void makeup(){
        //这是第一个人,先拿口红
        if(choice==0){
            synchronized(lip){//获得口红的锁
            System.out.println(this.girLnmae+"获得口红的锁");
                //休息一秒
                try {
                      Thread.sleep(1000);
                } catch(Exception e) {
                    System.out.println("休息异常");
                } 
                //休息后想拿到镜子
                synchronized(mir){//一秒钟后想获得镜子
                    System.out.println(this.girLnmae+"获得镜子的锁");
                }
              
            }
        }else{//这是第二个人,先拿镜子,这样做判断,就可以让他们互相都想获取对方的资源
            synchronized(mir){//获得镜子的锁
            System.out.println(this.girLnmae+"获得镜子的锁");
                //休息2秒
                try {
                      Thread.sleep(2000);
                } catch(Exception e) {
                    System.out.println("休息异常");
                } 
                //休息后想拿到镜子
                synchronized(lip){//2秒钟后想获得口红
                    System.out.println(this.girLnmae+"获得口红的锁");
                }
              
            }
        }
    }
}
//死锁:多个线程互相抱着对方需要的资源,然后形成僵持,解决方式
public class Main {
    public static void main(String[] args) {
        //0,为口红,1为镜子
        Makeuo g1=new Makeuo(0,"小红帽");//第一个人
        Makeuo g2=new Makeuo(1,"灰姑娘");//第二个人
        //启动这两个线程
        g1.start();
        g2.start();
        
        
    }
}

//口红
class Lipatic{
    
}

//镜子
class Mirrot{
}

//化妆
class Makeuo extends Thread{
    //需要的资源只有一份,用static来保证只有份
    static Lipatic lip=new Lipatic();//创建一个口红对象
    static Mirrot mir=new Mirrot();//创建一个镜子对象
    
    int choice;//选择
    String girLnmae;//使用化妆品的人
    //构造器
    Makeuo(int choice,String girLnmae){
        this.choice=choice;
        this.girLnmae=girLnmae;
    }
    public void run(){
        //化妆
        makeup();
        
    }
    
    //化妆方法,互相持有对方的锁,就是需要拿到对方的 
    private void makeup(){
        //这是第一个人,先拿口红
        if(choice==0){
            synchronized(lip){//获得口红的锁
            System.out.println(this.girLnmae+"获得口红的锁");
                //休息一秒
                try {
                      Thread.sleep(1000);
                } catch(Exception e) {
                    System.out.println("休息异常");
                } 
                //原本拿镜子的代码块是放在这里的,我们把他放到循环外面,不要同时抱对方的锁,就可以了
                }
                //休息后想拿到镜子
                synchronized(mir){//一秒钟后想获得镜子
                    System.out.println(this.girLnmae+"获得镜子的锁");
              
            }
        }else{//这是第二个人,先拿镜子,这样做判断,就可以让他们互相都想获取对方的资源
            synchronized(mir){//获得镜子的锁
            System.out.println(this.girLnmae+"获得镜子的锁");
                //休息2秒
                try {
                      Thread.sleep(2000);
                } catch(Exception e) {
                    System.out.println("休息异常");
                } 
                //原本拿口红的代码块是放在这里的,我们把他放到循环外面,不要同时抱对方的锁,就可以了
                }
                  //休息后想拿到口红
                synchronized(lip){//2秒钟后想获得口红
                    System.out.println(this.girLnmae+"获得口红的锁");
              
            }
        }
    }
}
死锁总结:
    解决死锁的方法是,不要同时抱对方需要的锁


产生条件:
        1.互斥条件:一个资源每次只能被一个进程使用。
        2.请求与保持条件:一个进程因请求资源而阻塞时,对方获得的资源保持不放。
        3.不剥夺条件:进程已获得的资源,在未使用完之前,不能强行剥夺。
        4.循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。
  上面的条件,我们只要想办法破解其中任意一个或者多个条件,就可避免死锁发生。

相关