Skip to main content

How do I avoid deadlocks

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 O1T1 then tries to obtain a write lock on object O2.
- Thread T2 obtains a write lock on object O2T2 then tries to obtain a write lock on object O1.

See sample code below.

Deadlock can be avoided as below:
  1. Avoid creating exclusive locks on multiple objects. Where possible create exclusive lock on a single object
  2. If #1 is not feasible, obtain locks in the same order and not in a different order
  3. Where possible use Locks and use shared locks instead of exclusive locks.
  4. 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