java如何可以创建一个系统。出来如何防止死锁?
我发现包括对系统的调用。出来经典的Java Deadlock Tutorial格式将防止死锁发生,我不知道为什么
下面的代码与本教程的代码相同,只是增加了main
的System.out.format("Hi, I'm %s...no deadlock for you!\n\n", alphonse.getName());
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) throws InterruptedException {
final Friend alphonse = new Friend("Alphonse");
final Friend gaston = new Friend("Gaston");
System.out.format("Hi, I'm %s...no deadlock for you!\n\n", alphonse.getName());
new Thread(new Runnable() {
public void run() { alphonse.bow(gaston); }
}).start();
new Thread(new Runnable() {
public void run() { gaston.bow(alphonse); }
}).start();
}
}
以下是输出:
Hi, I'm Alphonse...no deadlock for you!
Alphonse: Gaston has bowed to me!
Gaston: Alphonse has bowed back to me!
Gaston: Alphonse has bowed to me!
Alphonse: Gaston has bowed back to me!
删除有问题的行会导致通常的死锁:
Alphonse: Gaston has bowed to me!
Gaston: Alphonse has bowed to me!
... deadlock ...
是对系统的调用。出来格式化以某种方式改变线程获取对象的内在锁的方式
更新:
通过更改代码中线程的起始位置,我可以使系统再次死锁:
public static void main(String[] args) throws InterruptedException {
final Friend alphonse = new Friend("Alphonse");
final Friend gaston = new Friend("Gaston");
System.out.format("Hi, I'm %s...no deadlock for you!\n\n", alphonse.getName());
Thread t1 = new Thread(new Runnable() {
public void run() { alphonse.bow(gaston); }
});
Thread t2 = new Thread(new Runnable() {
public void run() { gaston.bow(alphonse); }
});
t1.start();
t2.start();
}
这就引出了一个问题,即我们如何能够更深入地了解线程调度程序的行为,但我将把它保存到另一天
# 1 楼答案
format()
和写入控制台通常是非常昂贵的操作。我猜它的执行改变了线程启动的时间,因此第二个线程启动得太晚,不会干扰第一个线程# 2 楼答案
您并没有真正移除死锁,而是(由于某些内部JVM原因)更改了线程的计时,以便其中一个线程在其他调用^{之前进入
bowBack()
。 只要输入bow
:sleep(1000)
,你的死锁就会再次出现请注意,死锁并不总是发生,只有当线程处于lucky定时时才会发生。在这种情况下,当两个线程都进入
bow
并且在它们调用bowBack
之前,就会发生死锁。。。 而“一些内部JVM原因”可以是:
在您的例子中,实际上有三个线程:执行main、t1和t2的线程。 放置print隐藏死锁的原因可能是线程调度程序决定
main
仍有工作要做,即刷新io缓冲区,因此让main在启动t1和启动t2之前继续。如果您使用的是双核cpu,则只有main
和t1
会运行,但t2
会等待,因为print
是一个缓慢的操作。上下文切换需要更多的时间,t1将在t2开始之前完成。。。这样就不会出现僵局。但这并不意味着如果再次运行程序,死锁就不会发生如果你想玩,创建一个
queue
并在该队列中推送令牌(线程名称),然后join
在main中推送你的线程。完成后,打印队列内容,您可以观察线程的计时