0

Can this code deadlock with thread 1 calling one and thread 2 calling two. That is, can the acquisition of the inner lock be reordered to before the acquisition of the outer one (from the POV of the other thread)?

private final Object foo = new Object();
synchronized  void one() {
    // ...
    synchronized(this.foo) {
       // ...
    }
    // ...
}

synchronized void two() {
    // ...
    synchronized(this.foo) {
       // ...
    }
    // ...
}
Artefacto
  • 96,375
  • 17
  • 202
  • 225

2 Answers2

0

No, this will not deadlock.

When synchronized methods are called the intrinsic lock of this is locked before the method’s body is executed. Here either thread 1 or thread 2 will get to run its method, and the other one will not be able to lock on the intrinsic lock of this.foo so the owner of the lock of this will be able to lock this.foo.

Victor Schubert
  • 323
  • 3
  • 8
0

So for with a Simple Test :

class LockTest implements Runnable {
    public final Object foo = new Object();
    boolean runOne;

    public LockTest(boolean runOne) {
        this.runOne = runOne;
    }

    synchronized void  one() {
        System.out.println("runnin one function");
        synchronized(this.foo) {
            try {
                System.out.println("Enter Sleep function one");
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    synchronized void  two() {
        System.out.println("running two function");
        synchronized(this.foo) {
            try {
                System.out.println("enter sleep function two");
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public void run() {
        if(runOne)
        one();
        else
            two();
    }
}

With this in a Main class :

while (true)
        {
            LockTest document2 = new LockTest(true);
            LockTest document3 = new LockTest(false);
            Thread tread1 = new Thread(document2);
            Thread tread2 = new Thread(document3);
            tread1.start();
            tread2.start();
            a++;
            if(a==10)
                break;

        }

We are not locking and even watching with a Thread Dump everything is working Fine. Why? Because every time we are initializating a new Thread with a new object foo. But if that object is declared as static it will be a lock and the others threads need to wait. So from my test and POV. No, it can't be deadlocked.

Gatusko
  • 2,503
  • 1
  • 17
  • 25