In this Q&A, we'll go over what's a deadlock and how to avoid it.
Deadlock is a condition when two or more threads are blocked on each other and waiting forever. This typically happens as below:
- Thread T1 obtains a write lock on object O1. T1 then tries to obtain a write lock on object O2.
- Thread T2 obtains a write lock on object O2. T2 then tries to obtain a write lock on object O1.
See sample code below.
Deadlock can be avoided as below:
- Avoid creating exclusive locks on multiple objects. Where possible create exclusive lock on a single object
- If #1 is not feasible, obtain locks in the same order and not in a different order
- Where possible use Locks and use shared locks instead of exclusive locks.
- When obtaining exclusive lock set a timeout with retry if the lock cannot be obtained within the set time.
package com.javahowdoi.thread;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class DeadlockDemo {
private static class DeadlockTask implements Runnable {
final Object s1 , s2;
boolean order;
DeadlockTask(Object s1, Object s2, boolean order) {
this.s1 = s1; this.s2 = s2; this.order = order;
}
@Override
public void run() {
if(order)
{
synchronized(s1) {
System.out.println("Synchronized on s1. About to wait for s2");
synchronized(s2) {
System.out.println("Got lock on s2. Avoided deadlock ");
}
}
}
else
{
// Note here that the order of synchronization is different
// This can lead to deadlock is string objects s1 and s2 are shared
synchronized(s2) {
System.out.println("Synchronized on s2. About to wait for s1");
synchronized(s1) {
System.out.println("Got lock on s1. Avoided deadlock ");
}
}
}
}
}
public static void main(String[] args ) {
ExecutorService es = Executors.newFixedThreadPool(2);
String s1 ="s1", s2 = "s2";
es.submit(new DeadlockTask(s1, s2, true));
es.submit(new DeadlockTask(s1, s2, false));
es.shutdown();
}
}
Comments
Post a Comment