One of the best mechanisms to avoid a deadlock situation in a concurrent application is to force tasks to always, get shared resources in the same order. An easy way to do this is to assign a number to every resource. When a task needs more than one resource, it has to request them in order.
For example, if you have two tasks, T1 and T2, and both need two resources, R1 and R2, you can force both to request the R1 resource first, and then the R2 resource. You will never have a deadlock.
On the other hand, if T1 first requests R1 and then R2, and T2 first requests R2 and then R1, you can have a deadlock.
For example, a bad use of this tip is as follows. You have two tasks that need to get two Lock objects. They try to get the locks in a different order:
public void operation1() {
lock1.lock();
lock2.lock();
.
}
public void operation2() {
lock2.lock();
lock1.lock();
}
It's possible that operation1() executes its first sentence and operation2() its first sentence too, so they will be waiting for the other Lock and you will have a deadlock.
You can avoid this simply by getting the locks in the same order. If you change operation2(), you will never have a deadlock, as follows:
public void operation2() {
lock1.lock();
lock2.lock();
}