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.