模拟死锁:person1获得goods1的锁,还想要goods2的锁,person2获得goods2的锁,还想要goods1的锁.但是运行结果没造成死锁


public class DeadLock {
    public static void main(String[] args) {
        MakeUp person1 = new MakeUp(0,"小王");
        MakeUp person2 = new MakeUp(1,"小李");
        person1.start();
        person2.start();
    }
}


//物品1
class Goods1{

}
//物品2
class Goods2{

}

class MakeUp extends Thread{
    private Goods1 goods1 = new Goods1();
    private Goods2 goods2 = new Goods2();

    int choice;
    String personName;

    MakeUp(int choice,String personName){
        this.choice = choice;
        this.personName = personName;
    }
    @Override
    public void run() {
        try {
            Change();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    public void Change() throws InterruptedException {
        if (choice == 0){
            synchronized (goods1){
                System.out.println(this.personName + "已经拥有goods1");
                Thread.sleep(1000);
                synchronized (goods2){
                    System.out.println(this.personName + "还想拥有goods2");
                }
            }
        }else {
            synchronized (goods2){
                System.out.println(this.personName + "已经拥有goods2");
                Thread.sleep(1000);
                synchronized (goods1){
                    System.out.println(this.personName + "还想拥有goods1");
                }
            }
        }
    }

}

运行结果:
小王已经拥有goods1
小李已经拥有goods2
小王还想拥有goods2
小李还想拥有goods1
然后就停止了

所谓死锁是当多个线程抢占同一份资源时,由于资源不足,导致线程死锁。
在你的实现中,两个线程并没有满足抢占相同资源问题,所以不会出现死锁现象。
处理方式:
方式一:MakeUp类中将Good1和Good2对象静态化,保证多次创建时只会创建一次。
方式二:MakeUp类中不实例化Good1对象,直接用Good1、Good2类对象作为同步锁参数。

代码实现:

public class DeadLockDemo {
    public static void main(String[] args) {
        MakeUp person1 = new MakeUp(0,"小王");
        MakeUp person2 = new MakeUp(1,"小李");
        person1.start();
        person2.start();
    }
}
//物品1
class Goods1{

}
//物品2
class Goods2{

}
class MakeUp extends Thread{
    //private static Goods1 goods1 = new Goods1();
    //private static Goods2 goods2 = new Goods2();
    int choice;
    String personName;

    MakeUp(int choice,String personName){
        this.choice = choice;
        this.personName = personName;
    }
    @Override
    public void run() {
        try {
            Change();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    public void Change() throws InterruptedException {
        if (choice == 0){
            synchronized (Goods1.class){
                System.out.println(this.personName + "已经拥有goods1");
                Thread.sleep(1000);
                synchronized (Goods2.class){
                    System.out.println(this.personName + "还想拥有goods2");
                }
            }
        }else {
            synchronized (Goods2.class){
                System.out.println(this.personName + "已经拥有goods2");
                Thread.sleep(1000);
                synchronized (Goods1.class){
                    System.out.println(this.personName + "还想拥有goods1");
                }
            }
        }
    }
}

person1和person2是不同的对象,他们都有自己的goods,除非你把里面的goods改成static,不然他们其实不是同一把锁