I have a class of common code that is thread safe.
One of the methods in that class is abstract and needs to be overridden for different implementations.
I need
You can't do it directly. One thing you can do is have the method be concrete, but invoke an abstract method:
public synchronized final void foo() {
doFoo();
}
protected abstract void doFoo();
That way, doFoo() will always* be invoked under the synchronization established by foo().
* unless someone invokes it directly, so you should name and document it to make it clear that they shouldn't.
This link to the JLS confirms that we can't mix abstract and synchronized.
Though much weaker than a keyword or standard annotation, but stronger than documentation: perhaps try a Marker interface?
... provides a means to associate metadata with a class where the language does not have explicit support for such metadata.
This is a stretch, but might help, in that the derived class makes a declaration (edit: new example tests the declaration):
interface EatMethodIsThreadSafe {}
abstract class Animal {
public Animal() {
if (! (this instanceof EatMethodIsThreadSafe)) {
throw new IllegalArgumentException("eat method must be thread safe");
}
}
public abstract void eat();
}
public class Bear extends Animal implements EatMethodIsThreadSafe {
public synchronized void eat() {}
public static void main(String...args) { Bear b = new Bear(); }
}
From Synchronized method in subclass
Synchronized is the implemenation detail of a method. You can override a sync method with a method without declaring that as sync and vice versa. The same holds true for the overloading also.
You can also have a look at, A synchronized method in the superclass acquires the same lock as one in the subclass.