我试图了解如何从https://docs.oracle.com/javase/tutorial/essential/concurrency/deadlock.html创建死锁。
我没有复制和粘贴示例代码,而是选择自己编写代码。
链接的最后一行说“两个块都不会结束,因为每个线程都在等待另一个退出弓”,但从未提及System.out.format。
然后我编写了下面的代码,它从未进入死锁
public class DeadlockTest {
static class Resource {
public synchronized void test1(Resource r) {
System.out.print("test1");
r.test2();
}
public synchronized void test2() {
System.out.print("test2");
}
}
public static void main(String... a) {
final Resource r1 = new Resource();
final Resource r2 = new Resource();
new Thread(new Runnable() {
public void run() {
r1.test1(r2);
}
}).start();
new Thread(new Runnable() {
public void run() {
r2.test1(r1);
}
}).start();
}
}
所以我试图逐行比较,发现只有print语句是错误的。我没有使用System.out.format,而是使用了System.out.print。所以代码永远不会陷入死锁状态。然后我将其更改为System.out.format,我能够模拟死锁。
我甚至从链接中复制了示例代码,将format语句更改为print / println并且没有进入死锁。
任何人都可以解释如何准确地创建死锁吗?
答案 0 :(得分:2)
我拿了你的代码来测试它。它确实运行良好。
只有当我在Thread.sleep(100)
中添加了String.format
或test1
时,它才会被阻止。好像你的“工作”方法(print
)太快了。在第二个线程通过调用test1
导致阻塞之前,第一个线程已经完成了test2
。
要留在教程示例中:您的主题实际上并没有“彼此鞠躬同时”,而只是“非常快地在彼此之后” 。使弓形慢一点,同时增加机会同时弯曲(仍然无法保证,例如,如果系统需要更长的时间来安排第二个线程)。