我想知道在下面的例子中避免死锁的替代方法是什么。下面的例子是一个典型的银行转账死锁问题。在实践中有哪些更好的方法来解决这个问题?
class Account {
double balance;
int id;
public Account(int id, double balance){
this.balance = balance;
this.id = id;
}
void withdraw(double amount){
balance -= amount;
}
void deposit(double amount){
balance += amount;
}
}
class Main{
public static void main(String [] args){
final Account a = new Account(1,1000);
final Account b = new Account(2,300);
Thread a = new Thread(){
public void run(){
transfer(a,b,200);
}
};
Thread b = new Thread(){
public void run(){
transfer(b,a,300);
}
};
a.start();
b.start();
}
public static void transfer(Account from, Account to, double amount){
synchronized(from){
synchronized(to){
from.withdraw(amount);
to.deposit(amount);
}
}
}
}我想知道如果我像下面这样在我的传输方法中分离嵌套锁,死锁问题是否会得到解决
synchronized(from){
from.withdraw(amount);
}
synchronized(to){
to.deposit(amount);
}发布于 2012-11-11 07:32:18
除了lock ordered的解决方案之外,您还可以通过在执行任何帐户转移之前在私有静态最终锁对象上进行同步来避免死锁。
class Account{
double balance;
int id;
private static final Object lock = new Object();
....
public static void transfer(Account from, Account to, double amount){
synchronized(lock)
{
from.withdraw(amount);
to.deposit(amount);
}
}这种解决方案的问题是私有静态锁限制系统“按顺序”执行传输。
另一种可能是每个帐户都有一个ReentrantLock:
private final Lock lock = new ReentrantLock();
public static void transfer(Account from, Account to, double amount)
{
while(true)
{
if(from.lock.tryLock()){
try {
if (to.lock.tryLock()){
try{
from.withdraw(amount);
to.deposit(amount);
break;
}
finally {
to.lock.unlock();
}
}
}
finally {
from.lock.unlock();
}
int n = number.nextInt(1000);
int TIME = 1000 + n; // 1 second + random delay to prevent livelock
Thread.sleep(TIME);
}
}这种方法不会发生死锁,因为这些锁永远不会被无限期地持有。如果当前对象的锁被获取,但第二个锁不可用,则释放第一个锁,线程在尝试重新获取锁之前休眠一段指定的时间。
https://stackoverflow.com/questions/13326861
复制相似问题