I am wondering what are the alternative ways to avoid deadlock in the following example. The following example is a typical bank account transferring deadlock problem. What
You can also create separate lock for each Account (in Account class) and then before doing transaction acquire both locks. Take a look:
private boolean acquireLocks(Account anotherAccount) {
boolean fromAccountLock = false;
boolean toAccountLock = false;
try {
fromAccountLock = getLock().tryLock();
toAccountLock = anotherAccount.getLock().tryLock();
} finally {
if (!(fromAccountLock && toAccountLock)) {
if (fromAccountLock) {
getLock().unlock();
}
if (toAccountLock) {
anotherAccount.getLock().unlock();
}
}
}
return fromAccountLock && toAccountLock;
}
After get two locks you can do transfer without worrying about safe.
public static void transfer(Acc from, Acc to, double amount) {
if (from.acquireLocks(to)) {
try {
from.withdraw(amount);
to.deposit(amount);
} finally {
from.getLock().unlock();
to.getLock().unlock();
}
} else {
System.out.println(threadName + " cant get Lock, try again!");
// sleep here for random amount of time and try do it again
transfer(from, to, amount);
}
}