日期:2014-05-20  浏览次数:20865 次

一个关于线程死锁的问题
第一段代码来自于 《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
===========================
说明我写的没有实现死锁,而区别仅仅在于输出语句上,为什么?

------解决方案--------------------
第一段代码准确的说是有会产生死锁的可能性,但不一定会发生死锁
你的第二段代码也是这样的,有可能但不一定会产生死锁
Java code

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();
    }
}