Lydon Ch
Lydon Ch

Reputation: 8815

Lock Acquisition Order

With the following code, if a thread calls LoggingWidget.doSomething(), what is the order of lock acquisition that the thread has to go through? (i.e. does it get the Lock on LoggingWidget first, and then gets the lock on Widget ? )

public class Widget {
   public synchronized void doSomething() {

   }
}

public class LoggingWidget extends Widget {
    public synchronized void doSomething() {
         System.out.println(toString() + ": calling doSomething");
         super.doSomething();
    }
}

Upvotes: 3

Views: 654

Answers (4)

Pravat Panda
Pravat Panda

Reputation: 1090

There is only one lock bcoz there is only one object, but if the sub-class object's doSomething() method is called, the same lock is acquired twice. In JVM, the owner(thread) is same but it sets the acquisition count to two. The acquisition count is decremented each time when the owning thread exists the synchronized block. So here it would be decremented twice down to zero when the lock is finally released, one for each synchronized block.

Upvotes: 2

Shervin Asgari
Shervin Asgari

Reputation: 24499

If you want to ensure you get the correct lock of type LoggingWidget and not Widget you can do this:

public class LoggingWidget extends Widget {
  private final Object readLock = new Object();

  public void doSomething() {
    synchronized (readLock) {
      System.out.println(toString() + ": calling doSomething");
      super.doSomething();
    }
  }
}

Or if you use Lombok you can just write

public class LoggingWidget extends Widget {
  @Synchronized("readLock")
  public void doSomething() {
    System.out.println(toString() + ": calling doSomething");
      super.doSomething();
  }
}

Upvotes: 0

Michael Borgwardt
Michael Borgwardt

Reputation: 346327

In Java, they're caleld monitors and are per object. In your example, there is only one monitor.

Upvotes: 1

cletus
cletus

Reputation: 625147

The lock in this case is on this so there is only one lock, that being the instance. If there are more than one instance, each has an entirely separate lock regardless of whether it is a Widget or a LoggingWidget.

Let me put it another way. Your code is semantically equivalent to:

public class Widget {
  public void doSomething() {
    synchronized (this) {
      // do stuff
    }
  }
}

public class LoggingWidget extends Widget {
  public void doSomething() {
    synchronized (this) {
      System.out.println(toString() + ": calling doSomething");
      super.doSomething();
    }
  }
}

Only one of these methods is called so there's only one lock.

Upvotes: 3

Related Questions