How can I ensure that an overridden method is synchronized
Asked Answered
B

3

26

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 to ensure or at least flag to other developers that all implementations of this method need to be thread-safe.

What is the best way to do this?

Is there a keyword or annotation to this effect?

I have already tried abstract synchronized but that combination of keywords is not allowed.

Barbarism answered 2/10, 2012 at 5:9 Comment(0)
M
28

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.

Midian answered 2/10, 2012 at 5:18 Comment(2)
Slight refinement: make the public method final.Debug
Perfect. I don't know why I didn't of that, so simple.Barbarism
A
1

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.

Apotropaic answered 2/10, 2012 at 5:25 Comment(0)
D
0

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(); } 
}
Dowson answered 2/10, 2012 at 7:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.