我试图了解如何从 https://docs.oracle.com/javase/tutorial/essential/concurrency/deadlock.html 创建死锁。
我没有选择复制粘贴示例代码,而是选择自己编写。
链接中的最后一行说“两个 block 都不会结束,因为每个线程都在等待另一个线程退出弓”,但从未提及 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,并且能够模拟死锁。
我什至从链接中复制了示例代码,将格式语句更改为 print/println 并且它没有进入死锁。
谁能解释一下如何准确地创建死锁吗?
最佳答案
我拿了你的代码来测试它。确实运行得很好。
只有当我在 test1
中添加 Thread.sleep(100)
或 String.format
时,它才会阻塞。看起来你的“工作”方法(print
)太快了。在第二个线程通过调用 test1
导致阻塞之前,第一个线程已经完成了 test2
。
仍以教程为例:您的线程实际上并没有“同时互相鞠躬”,而只是“很快地彼此鞠躬” 。让鞠躬速度慢一点,可以增加他们同时鞠躬的机会(仍然不能保证,例如,如果系统需要更长的时间来安排第二个线程)。
关于java - 了解死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47695991/