Wednesday, December 31, 2008

Double Check in Java is broken .. not

Coders from the C world are most likely to use the so called double check idiom at some point of their coding career. If those same coders (like me) do their first multithreaded app in java will probably run into some problems.After my first trials with java several years ago I ran into some pretty weird problems. Sometimes my nice apps would expose the weirdest behaviour. After searching around I got educated in a newsgroup.
Before I start to explain what the problem is I should probably explain what double-check is.
Let's say there is a certain object that needs to be initialized. An initialization should only take place once. Sometimes it might be required to postpone the initialization until the first use of the object (lazy init) or until certain conditions in the systems are met (service orientated architectures).
The following piece of code illustrates the naive approach:>

Test initValue=null;

if(initValue==null){
synchronized(this){
if(initValue==null){
initValue=new Test();
}
}
}
So we first check if the variable has been initialized, if not we synchronize and check again and if this second check is succeeds we do the init work. The second check is done because another thread might have initilaized in the meantime.
The problem is that this won't work in Java. The JDK does a lot of work under the hood. On of these things is that threads can keep a local copy of variables. This behavior completely breaks double check.
That's where my story ended some years ago. I never touched it or bothered researching into it again.
Until I recently discovered atomic variables in Java and stumbled over the new memory model introduced with JDK 5.
After reading up on it I finally found the solution to fix double-check:
The volatile keyword.
Volatile indicates that the variable will be modified by several threads. This tells the JVM that threads are simply not allowed to keep local copies of variables.
Fixed double check locking looks like this:
volatile Test initValue=null;<br />if(initValue==null){<br />    synchronized(this){<br />        if(initValue==null){<br />            initValue=new Test();<br />        }<br />    }<br />}

Yep, I got my double-check locking back but there are still some things to consider:
  • Performance: If using volatile on a variable better do some benchmarking.
  • JDK 5: Yep, volatile only works like this with JDK 5 and later.



Wednesday, December 10, 2008

Spring, @Comparable, OSGi, Eclipse RCP in Eclipse Magazin

I wanted to post how I got Spring to use AspectJ for DI in Eclipse RCP applications. The post won't happen as I wrote an article about it for the German Eclipse Magazin. As soon as the article is out you will find a link to it in here.