Wednesday, May 08, 2013

Java synchronized methods: lock on object or class

http://stackoverflow.com/questions/437620/java-synchronized-methods-lock-on-object-or-class

In section 8.1.1 of the Java Language
Specification, third edition. The valid modifiers for a class are any
annotation, public, protected, private, abstract, static, final, or
strictfp. It is illegal to place the keyword "synchronized" in front of
a class.

The Java Tutorials say: "it is not possible for two invocations of synchronized methods on the same object to interleave." What does this mean for a static method? Since a static method has no associated object, will the synchronized keyword lock on the class, instead of the object?
Yes.

Synchronized method acquires a monitor (§17.1) before it executes. For a class (static) method, the monitor associated with the Class object for the method's class is used. For an instance method, the monitor associated with this (the object for which the method was invoked) is used.

One point you have to be careful about (several programmers generally fall in that trap) is that there is no link between synchronized static methods and sync'ed non static methods, ie:
class A {
static synchronized f() {...}
synchronized g() {...}
}

Main:

A a = new A();
Thread 1:

A.f();
Thread 2:

a.g();
f() and g() are not synchronized with each other and thus can execute totally concurrently.

Unless you implement g() as follows:
g() {
synchronized(getClass()) {
...
}
}
I find this pattern useful also when I want to implement mutual exclusion between different instances of the object (which is needed when accesing an external resource, for example).

No comments: