Why can't an abstract method be synchronized?

ahodder picture ahodder · Oct 9, 2012 · Viewed 12.1k times · Source

I was reading a thread from CodeRanch saying that abstract methods could not be synchronized due to the fact that an abstract class cannot be instantiated, meaning no object to lock.

This doesn't make sense since an abstract class is a definition (contract) for a child class. The abstract definition of a synchronized method does not need to lock, the child does. All the abstract heading would indicate is that the child must synchronize this method. Is my logic on this correct? If not can someone explain why I'm wrong?

Answer

Jon Skeet picture Jon Skeet · Oct 9, 2012

The comment about not being able to instantiate the abstract class is garbage. Given that it has to be an instance method to be abstract, there certainly is a reference which could be locked on. Concrete methods in abstract classes can still refer to this. However, that still doesn't mean that abstract classes should be able to be synchronized.

Whether or not a method is synchronized is an implementation detail of the method. Synchronization isn't specified anywhere as a declarative contract - it's not like you can synchronize in interfaces, either.

How a class implements whatever thread safety guarantees it provides is up to it. If an abstract class wants to mandate a particular approach, it should use the template method pattern:

// I hate synchronizing on "this"
private final Object lock = new Object();

public final void foo() {
    synchronized(lock) {
        fooImpl();
    }
}

protected abstract void fooImpl();

That's pretty dangerous in itself though, given that it's effectively calling "unknown" code within a lock, which is a recipe for deadlocks etc.