We use lock to ensure thread safety, but indiscriminate use of locking can cause lock-ordering deadlocks.
# deadly embrace
When thread A holds lock L and try to acquire lock M, but at the same time thread B holds lock M and try to acquire lock L, both threads will wait forever.
# lock-ordering deadlock
This problem come about when two threads attempt to acquire the same locks in different order.
A program will be free of lock-ordering deadlocks if all threads acquire the locks they need in a fixed order.
/** code sample for lock-ordering deadlock */
public class LeftRightlock {
private final Object left = new Object();
private final Object right = new Object();
public void leftRight() {
synchronized (left) {
synchronized (right) {
// ...
}
}
}
public void rightLeft() {
synchronized (right) {
synchronized (left) {
// ...
}
}
}
}
# dynamic lock order deadlock
in fact, the lock order depends on the order of arguments passed to the method:
public void transferMoney(final Account fromAcct,
final Account toAcct,
final double amount) throws Exception {
synchronized (fromAcct) {
synchronized (toAcct) {
if (fromAcct.getBalance() < amount) {
throw new Exception("insufficient balance");
} else {
fromAcct.debitt(amount);
toAcct.credit(amount);
}
}
}
}
to solve the above problem, we can use System.identityHashCode(obj) to decide the order.
# Avoid deadlock
One technique for detecting and recovering from deadlocks is to use timed tryLock of the explicit lock instead of intrinsic locking.
#starvation
Startvation occurs when a thread perpetually denied access to resources it needs.
Starvation can be caused by inappropriate use of thread priorities.
# priority
The thread API defines 10 priority levels that JVM can map to OS scheduling priorities, this mapping is platform-specific. Some different java priorities can map to same OS priority.
# livelock
Livelock is also a form of liveness failure in which a thread, while not blocked, still cannot make progress because it keeps retrying an operation that will always fail.
The solution for livelock is to introduce some randomness into retry mechanism.