第一段代码来自于 《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
===========================
说明我写的没有实现死锁,而区别仅仅在于输出语句上,为什么?
=================================
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
===========================
说明我写的没有实现死锁,而区别仅仅在于输出语句上,为什么?
你的第二段代码也是这样的,有可能但不一定会产生死锁
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();
}
}
书上的例子只能说可能会造成死锁,不是必然会发生死锁,书上的解释是想当然的把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
这样的随机性是因为线程本身的执行是随机的原因造成的