第一段代码来自于 《The Java Tutorial》
=================================
public class Deadlock {
    static class Friend {
        private final String name;
        public Friend(String name) {
            this.name = name;
        }
        public String getName() {
            return this.name;
        }
        public synchronized void bow(Friend bower) {
            System.out.format("%s: %s has bowed to me!%n", 
                    this.name, bower.getName());
            bower.bowBack(this);
        }
        public synchronized void bowBack(Friend bower) {
            System.out.format("%s: %s has bowed back to me!%n",
                    this.name, bower.getName());
        }
    }    public static void main(String[] args) {
        final Friend alphonse = new Friend("Alphonse");
        final Friend gaston = new Friend("Gaston");
        new Thread(new Runnable() {
            public void run() { alphonse.bow(gaston); }
        }).start();
        new Thread(new Runnable() {
            public void run() { gaston.bow(alphonse); }
        }).start();
    }
}输出如下:
Alphonse: Gaston has bowed to me!
Gaston: Alphonse has bowed to me!=============================
第二段是我看了上面这段代码之后自己写的基本一摸一样,唯一的区别在于红字处public class DeadLockTest
{
static class BadMan
{
private final String name;

public BadMan(String name)
{
this.name=name;
}

public String getName()
{
return this.name;
}

public synchronized void bow(BadMan bower)
{
System.out.println(this.name+" :"+bower.getName()+" has bowed to me");
bower.bowBack(this);

}

public synchronized void bowBack(BadMan bower)
{
System.out.println(this.name+" :"+bower.getName()+" has bowed back to me");

}
}
public static void main(String[] args)
{
final BadMan ma=new BadMan("ma");
final BadMan li=new BadMan("li");

new Thread(new Runnable()
{
public void run()
{
ma.bow(li);
}
}).start();

new Thread(new Runnable()
{
public void run()
{
li.bow(ma);
}
}).start();
}
}输出
li :ma has bowed to me
ma :li has bowed back to me
ma :li has bowed to me
li :ma has bowed back to me
===========================
说明我写的没有实现死锁,而区别仅仅在于输出语句上,为什么?

解决方案 »

  1.   

    第一段代码准确的说是有会产生死锁的可能性,但不一定会发生死锁
    你的第二段代码也是这样的,有可能但不一定会产生死锁
    public class Test {
    static class BadMan {
    private final String name;
    private boolean flag = true; public BadMan(String name) {
    this.name = name;
    } public String getName() {
    return this.name;
    } public synchronized void bow(BadMan bower) {
    System.out.println(this.name + " :" + bower.getName()
    + " has bowed to me");
    if (flag) {
    Thread.currentThread().yield();
    flag = false;
    } else {
    flag = true;
    }
    bower.bowBack(this); } public synchronized void bowBack(BadMan bower) {
    System.out.println(this.name + " :" + bower.getName()
    + " has bowed back to me");
    }
    } public static void main(String[] args) {
    final BadMan ma = new BadMan("ma");
    final BadMan li = new BadMan("li"); new Thread(new Runnable() {
    public void run() {
    ma.bow(li);
    }
    }).start(); new Thread(new Runnable() {
    public void run() {
    li.bow(ma);
    }
    }).start();
    }
    }
      

  2.   

    因为线程的执行是随机的,线程的CPU分配时间由系统调度
    书上的例子只能说可能会造成死锁,不是必然会发生死锁,书上的解释是想当然的把CPU的分配时间顺序化了,所以导致死锁,而你的代码是实际运行中CPU时间的随机分配,所以不一定发生死锁。
    导致死锁的可能执行顺序是这样的--情况1
    线程1执行alphonse.bow(gaston); 
    在bower.bowBack(this);被执行之前,线程1的CPU权限被收回,系统把CPU分给线程2
    接着线程2执行gaston.bow(alphonse); 
    此时死锁形成,当线程1重新获得CPU想执行bower.bowBack(this);的时候,需要等待线程2放锁,同样的,当线程2想执行bower.bowBack(this);的时候,需要等待线程1放锁,所以造成彼此等待,也就是死锁导致不死锁的执行顺序是这样的--情况2
    线程1执行alphonse.bow(gaston); 线程1的CPU没有被回收,继续执行bower.bowBack(this);然后线程1结束
    接下来线程2执行,调用gaston.bow(alphonse); 因为线程1已经结束了,所以线程2执行bower.bowBack(this);的时候,已经不用等待线程1了所以书上的代码发生了 情况1, 而LZ你的代码发生了 情况2
    这样的随机性是因为线程本身的执行是随机的原因造成的