【发布时间】:2013-06-24 05:20:17
【问题描述】:
假设有以下 Account 类的两个对象 - account1 和 account2。并且有两个线程T1和T2。
T1 正在将金额 100 从 account1 转移到 account2,如下所示:
account1.transfer(account2, 100);
同样,T2 正在将金额 50 从 account2 转移到 account1:
account2.transfer(account1, 50);
transfer() 方法显然容易出现死锁,因为两个线程 T1 和 T2 会尝试以相反的顺序获取锁。 (线程 T1 会先尝试获取 account1 的锁,然后再获取 account2。而线程 T2 会尝试获取 account2 的锁,然后再获取 account1。)
确保始终保证锁定顺序的最佳方法是什么(在这种情况下)?
public class Account {
private float balance;
public class Account() {
balance = 5000f;
}
private void credit(float amt) {
balance += amt;
}
// To exclude noise assume the balance will never be negative
private void debit(float amt) {
balance -= amt;
}
// Deadlock prone as the locking order is not guaranteed
public void transfer(Account acc2, float amt) {
synchronized(this) {
synchronized(acc2) {
acc2.debit(amt);
this.credit(amt);
}
}
}
}
【问题讨论】:
-
我刚刚在此处发布了一个解决此问题的答案:stackoverflow.com/questions/29424306/…
-
我还发布了一个类似问题的答案,该解决方案无需重新排序且仅对原始代码进行最小更改即可工作:stackoverflow.com/questions/29424306/…
标签: multithreading locking deadlock