new Thread(new BigHammer(gun,bullet)).start();
new Thread(new TwoDog(gun,bullet)).start();
这种无法死锁
但是 下面这种可以死锁
BigHammer big = new BigHammer(gun,bullet);
TwoDog two =new TwoDog(gun,bullet);
new Thread(big).start();
new Thread(two).start();
大锤线程对象
public class BigHammer implements Runnable {
private Object gun;
private Object bullet;
public BigHammer(Object gun, Object bullet) {
this.gun = gun;
this.bullet = bullet;
}
@Override
public void run() {
synchronized (bullet) {
System.out.println("大锤捡到了子弹");
synchronized (gun) {
System.out.println("大锤拿到了M4");
System.out.println("大锤开火了二狗英勇就义");
}
}
}
}
二狗线程对象
public class TwoDog implements Runnable{
private Object gun;
private Object bullet;
public TwoDog(Object gun, Object bullet) {
this.gun = gun;
this.bullet = bullet;
}
@Override
public void run() {
synchronized (gun){
System.out.println("二狗拿到了M4");
synchronized (bullet){
System.out.println("二狗捡到了子弹");
System.out.println("二狗开火了大锤英勇就义");
}
}
}
}
测试类
public class Test {
public static void main(String[] args) {
Object gun = new Object();
Object bullet = new Object();
BigHammer big = new BigHammer(gun,bullet);
TwoDog two =new TwoDog(gun,bullet);
new Thread(big).start();
new Thread(two).start();
// new Thread(new BigHammer(gun,bullet)).start();
// new Thread(new TwoDog(gun,bullet)).start();
}
}
当使用 new Thread(new BigHammer(gun,bullet)).start();
new Thread(new TwoDog(gun,bullet)).start();时,运行结果为
大锤捡到了子弹
大锤拿到了M4
大锤开火了二狗英勇就义
二狗拿到了M4
二狗捡到了子弹
二狗开火了大锤英勇就义
当使用 BigHammer big = new BigHammer(gun,bullet);
TwoDog two =new TwoDog(gun,bullet);
new Thread(big).start();
new Thread(two).start();时运行结果为
二狗拿到了M4
大锤捡到了子弹
先new出对象再用可以实现,直接在线程对象里面new实现不了死锁
弄清以上两种不同结果的原因是什么
你加个 Thread.sleep()方法中断一下试试,我觉得在一个线程new对象的过程中,另外一个线程已经执行完,释放锁了
直接new 也会出现死锁的,这个只是概率性问题。你的run方法体中出现的枷锁是会出问题的,因为两个对象的前后加的锁都是同一个对象,而且前后顺序正好相反,导致在程序运行中,BigHammer 等待 TwoDog 释放gun,TwoDog 等待 Bighammer释放 bullet ,两者互不释放对方所需要的锁就会出现这个问题。可以把其中的一个加锁顺序调换一下,比如先加 gun 再加 bullet 。
至于你说的第二种没有出现死锁,你可以多跑几下试试 肯定会有的