提问人:Java_dev_dev 提问时间:10/5/2023 更新时间:10/5/2023 访问量:50
无法在嵌套同步的 java 中模拟死锁
Unable to simulate deadlock in java with nested synchronized
问:
我正在玩 Java 中的线程,并决定模拟死锁情况,但无法做到。
在嵌套的同步块之间添加语句之前,以下代码不会导致死锁情况:
public class Main {
public static class Account {
String name;
AtomicInteger money = new AtomicInteger(0);
void deposit(final int amount){
money.addAndGet(amount);
}
void withdraw(final int amount){
money.getAndAdd(-amount);
}
}
public static void main(String[] args) throws ExecutionException, InterruptedException, Exception {
int n = 5000;
for (int i = 0; i < n; i++) {
Thread thread1 = new Thread(() -> transfer(account1, account2, 1));
Thread thread2 = new Thread(() -> transfer(account2, account1, 2));
thread1.start();
thread2.start();
thread1.join();
thread2.join();
}
}
public static void transfer(Account from, Account to, int amount){
System.out.println("Hello from :" + Thread.currentThread());
synchronized(from){
// If bellow line is uncommented deadlock will occur, otherwise not
// System.out.println();
synchronized(to){
from.withdraw(amount);
to.deposit(amount);
}
}
}
}
根据我的理解,这应该以死锁告终,尤其是在运行模拟 5k 次时,但是在将 n 设置为任意大 int 后,应用程序将成功终止。在两个嵌套的同步语句之间添加简单的 println 语句后:
synchronized(from){
**System.out.println();**
synchronized(to){
我陷入了僵局。
我很困惑为什么当同步之间没有语句时它不会发生。我是否遗漏了什么,或者存在一些固有的 Java 机制(优化),如果没有中间语句,它会让一个线程优先于嵌套同步?或者它只是我的机器/JVM/OS 组合?
答:
1赞
Solomon Slow
10/5/2023
#1
据我了解,这应该以僵局告终。
不。它最终可能会陷入僵局,但如果没有这些电话,机会就很小了。当我说“渺茫”时,我说的是那种渺茫的机会;我工作的一家公司对新产品进行了数周的测试,在所有测试通过后,我们将其交付给十几个客户。然后,客户运行了半年,然后其中一个客户的服务器上发生了死锁,中断了他们的电子商务网站。(*我*通过研究他们发回给我们的 4Gb 核心文件来弄清楚发生了什么,这是一项有趣的工作。println
如果没有这些电话,*MUCH*更有可能发生的事情是;任何一个线程在另一个线程有机会尝试之前锁定两个互斥锁,它完成它的工作,然后轮到另一个线程。println
评论