Overriding synchronized methods in Java

Markus A. picture Markus A. · Mar 13, 2013 · Viewed 9.7k times · Source

Let's say I have a synchronized method on some class:

abstract class Foo {
    public synchronized void foo() {  // synchronized!
        // ...
    };
}

and I overrode it without using the synchronized modifier:

class Bar extends Foo {
    @Override
    public void foo() {               // NOT synchronized!
        super.foo();
        // ...
    }
 }

I have a couple of specific question regarding this scenario:

  1. Will the overridden method be implicitly synchronized as well?
  2. If not, will the super-call be synchronized?
  3. If there is no super-call, will anything be synchronized?
  4. Is there a way to force an overriding method to use synchronized (I noticed that abstract method definitions or method definitions inside an interface don't allow the synchronized keyword)?

Answer

Tom Hawtin - tackline picture Tom Hawtin - tackline · Mar 13, 2013
public synchronized void foo() {  // synchronized!
    // ...
};

Is essentially the same as:

public void foo() {
    synchronized (this) {  // synchronized!
        // ...
    }
};

The latter is more explicit, so I would generally suggest using that form. Or better using a lock that is a private field instead of the "outer" object.

So: 1. No. 2. Yes. 3. No. 4. Mark the method final and call a protected method that may be overridden.

public final void foo() {
    synchronized (this) {
        fooImpl();
    }
};
protected void fooImpl() {
    // ...
}

As ever, you may well be better off with delegation rather than subclassing.