I read somewhere:
If the static synchronized methods are located in different classes, then one thread can execute inside the static synchronized methods of each class. One thread per class regardless of which static synchronized method it calls.
Suppose I have below class hierarchy:
public class Base {
public static synchronized void printBase() {
System.out.println("Inside Base");
}
}
public class Derived extends Base {
public static synchronized void printDerived() {
System.out.println("Inside Derived");
}
}
1) If I have below two function calls:
Base.printBase();
Derived.printDerived();
As I understand they should not block each other and both could be executing at the same time. As the calls are made with different classes.
2) However if I have below two function calls:
Derived.printBase();
Derived.printDerived();
They should be blocked by each other as they are called on the same class. Right?
Or is there something more to this?
No, the behaviour you're describing in point 2 isn't what you'll see.
The synchronization object is dependant on where the method is declared, not on how it's called. From JLS 8.3.4.6:
For a class (static) method, the monitor associated with the Class object for the method's class is used.
The "method's class" here is Base.class
for printBase
, and Derived.class
for printDerived
. So the code is broadly equivalent to:
public class Base {
public static void printBase() {
synchronized (Base.class) {
System.out.println("Inside Base");
}
}
}
public class Derived extends Base {
public static void printDerived() {
synchronized (Derived.class) {
System.out.println("Inside Derived");
}
}
}
So those two methods can be invoked from different threads regardless of how they're called, without blocking each other. (Of course, if one of the threads already owns the monitor to Derived.class
, that will prevent a different thread from calling printDerived
etc - I'm only talking about how these methods interact with each other.)
See more on this question at Stackoverflow