6

Why can static and default interface methods not be synchronized?

People say that synchronized is an implementation detail. Well, strictfp is an implementation detail as well, but that doesn't prevent allowing strictfp on static and default interface methods.

A default method is inherited and it may be quite convenient to have it already synchronized if the class implementing the interface does not override the default method.

I have a guess that synchronized (as well as strictfp) is not inherited (am I right here?), but that does not explain why strictfp is allowed for static and default interface methods either.

Boann
  • 48,794
  • 16
  • 117
  • 146
Code Complete
  • 3,146
  • 1
  • 15
  • 38
  • 1
    This question bridges two question boundaries. You'll find the answer in two duplicates, but I'm not comfortable with that. It would feel disjoint to someone else looking for an answer if they had to look in two places to get *one* answer. – Makoto Dec 13 '17 at 17:50
  • Reasons for static methods and interface methods are probably different: `synchronized` locks on `this`, and there is no `this` in static methods. And for interfaces, as others noted, it's an implementation detail which should not be specified on method declaration. Not sure though why it's not allowed on default interface methods, as it indeed might be useful, as described by you. – Maciek Dec 13 '17 at 17:52

3 Answers3

6

The strictfp keyword ensures that your floating-point operations are consistent across all platforms. stricftp then becomes a guarantee of the JVM that your floating-point operations are going to be the same on all platforms, and that one can expect that floating-point operations are portable and consistent throughout.

A method marked synchronized is actually an implementation detail, and cannot be dictated or controlled by any one interface for any of its implementations. It was intentionally excluded from default methods, as explained by Brian Goetz, due to them being inherently dangerous (emphasis mine):

...So, why are they dangerous? Synchronization is about locking. Locking is about coordinating shared access to mutable state. Each object should have a synchronization policy that determines which locks guard which state variables. (See Java Concurrency in Practice, section 2.4.)

...It is the class that owns the state that gets to determine that object's synchronization policy. But interfaces do not own the state of the objects into which they are mixed in. So using a synchronized method in an interface assumes a particular synchronization policy, but one which you have no reasonable basis for assuming, so it might well be the case that the use of synchronization provides no additional thread safety whatsoever (you might be synchronizing on the wrong lock).

Community
  • 1
  • 1
Makoto
  • 104,088
  • 27
  • 192
  • 230
2

I think this is because if it were allowed:

interface I {
    static synchronized void x() {
    }
}

class C implements I {
    synchronized static void y() {
    }
}

then two different threads could enter C.y() and C.x() because x() is synchronized on I.class and y() on C.class. It is only my guess

Evgeniy Dorofeev
  • 133,369
  • 30
  • 199
  • 275
  • If we follow the same logic then we should not allow `synchronized` on abstract classes or any concrete class that is a parent class. – tsolakp Dec 13 '17 at 18:06
0
class C {
    public synchronized void f () {
    }
}

is the same as

class C {
    public void f () {
        synchronized(this){
        }
    }
}

If f were static, there would be no this object to synchronize on.

puhlen
  • 8,400
  • 1
  • 16
  • 31