Search code examples
javamultithreadingdeadlockreentrantlock

Understanding deadlock with a simple example


I am working on understanding deadlock basics so I came up with below code. I have two threads acquiring locks in opposite order but they're not deadlocking. When I run it I see all the printouts. What am I doing wrong?

public class DeadlockBasics {
  private Lock lockA = new ReentrantLock();
  private Lock lockB = new ReentrantLock();

  public static void main(String[] args) {
    DeadlockBasics dk = new DeadlockBasics();
    dk.execute();
  }

  private void execute() {
    new Thread(this::processThis).start();
    new Thread(this::processThat).start();
  }

  // called by thread 1
  public void processThis() {
    lockA.lock();
    // process resource A
    System.out.println("resource A -Thread1");

    lockB.lock();
    // process resource B
    System.out.println("resource B -Thread1");

    lockA.unlock();
    lockB.unlock();
  }

  // called by thread 2
  public void processThat() {
    lockB.lock();
    // process resource B
    System.out.println("resource B -Thread2");

    lockA.lock();
    // process resource A
    System.out.println("resource A -Thread2");

    lockA.unlock();
    lockB.unlock();
  }
}

Solution

  • First of all there is no garantee which threads is start first. To get the deadlock one of the thread has to take a lock on lockA and then the second thread has to take a lock on lockB or visa versa.

    public void processThis() {
        lockA.lock();
        // here the control should be switched to another thread
        System.out.println("resource A -Thread1");
    
        lockB.lock();
        ...
    

    But there may not be enough time to switch between thread because you have just a few lines of code.. It is too fast. To emulate some long work add delay before the second lock to both methods

    lockA.lock();
    Thread.sleep(200);  // 200 milis
    

    Then the second thread will be able to lock lockB before the first release both of them