Overriding synchronized methods in Java
JavaOverridingSynchronizedJava Problem Overview
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:
- Will the overridden method be implicitly synchronized as well?
- If not, will the
super
-call be synchronized? - If there is no
super
-call, will anything be synchronized? - 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)?
Java Solutions
Solution 1 - Java
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.
Solution 2 - Java
Failing to use synchronized when overriding a synchronized method has the potential for causing runtime bugs. As a safeguard, there is an Eclipse checker you can turn on to detect this condition. The default is "ignore". "Warning" is also a valid choice.
which will produce this message: