OT: IG double-checking locking

I just found this inspection and read the related document.
Wow! Does the jvm-spec really allow such disordered calls?
Example:
private Helper helper = null;
public Helper getHelper() {
if (helper == null)
synchronized(this) {
if (helper == null)
helper = new Helper();
}
return helper;
}
// other functions and members...
}

In
http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html
they wrote, that the compiler/jvm is allowed to execute the 'helper=new
Helper()' in the following (symbolic) way:
helper=allocateSpaceForObject(Helper.class)
helper.callConstructor()

This totally breaks my understanding of execution order.

4 comments
Comment actions Permalink

The key here is that execution order only applies with respect to a single thread of execution. Two threads rummaging about in the same code path need proper locking to exibit the Right(tm) execution order.

Given only one thread executing that piece of code you can make Happens Before-assumptions that look logical, given two threads and either no, or erroneous, locking you cannot.

The compiler (anything that assumes an instruction order changing role) is going to re-arrange the instructions in ways that, given a context with one thread, preserves all correct Happens Before-assumptions. A second thread entering that same context can and will break those .

0
Comment actions Permalink

Wasn't the memory model slightly adjusted in Java 5, so that the double checked locking is now valid?
So maybe the inspection should not trigger for language level 5.

Patrik Andersson schrieb:

The key here is that execution order only applies with respect to a single thread of execution. Two threads rummaging about in the same code path need proper locking to exibit the Right(tm) execution order.

Given only one thread executing that piece of code you can make Happens Before-assumptions that look logical, given two threads and either no, or erroneous, locking you cannot.

The compiler (anything that assumes an instruction order changing role) is going to re-arrange the instructions in ways that, given a context with one thread, preserves all correct Happens Before-assumptions. A second thread entering that same context can and will break those .

0
Comment actions Permalink

I read the same, but there is no official statement from Sun. Neither in
the JSR133, nor in the Java5 release notes.
And if I understood this correctly, the pattern can be used but the
related field must be declared 'volatile'.

Stephen Kelvin schrieb:

Wasn't the memory model slightly adjusted in Java 5, so that the double
checked locking is now valid?
So maybe the inspection should not trigger for language level 5.

0
Comment actions Permalink

Sounds stupid. How often do you have calls to static methods with lazy-init code in them stuck in tight loops?

0

Please sign in to leave a comment.