Concurrency
Deadlocks
Here is a code that could result in deadlock. Imagine one thread calls lockAndSave and another threads call lockAndLoad.
public static Object cacheLock = new Object();
public static Object tableLock = new Object();
public void lockAndSave() {
synchronized (cacheLock) {
synchronized (tableLock) {
save();
}
}
}
public void lockAndLoad() {
synchronized (tableLock) {
synchronized (cacheLock) {
load();
}
}
}The issue here is that the locks are not in the same order. Lets make the locking in the same order. Could a deadlock occur with this code? No, the code below would never dead lock.
Another example of deadlock situation is when two classes that have synchronized methods, call each other.
Imagine two threads, at the same time, first calls updateModel and second calls somethingChanged.
We can try to run this code and verify that we will get a deadlock.
Hidden deadlocks
We can write a code that will result in deadlock and it won't be that obvious. We could face to deadlock situation even with this code.
What if, at the same time, one thread calls transferMoney(accountOne, accountTwo, amount) and other thread calls transferMoney(accountTwo, accountOne, amount)? It will result in dead lock.
How to avoid dead lock
We should shrink synchronized blocks to a minimum. To make them more readable and avoid confusions. If we can't shrink it, we need to provide extra documentation and explain why we had to do it and what should other people be aware of.
Avoid acquiring multiple locks at a time. If we really have to have multiple locks, we need to make sure they are defined in a consistent order.
We might have to order the objects that are passed as argument, so the locking is always done in the same way.
See the original explanation, this article about deadlocks.
Last updated
Was this helpful?