Re: JavaMemoryModel: Will this solution work?

From: Jeremy Manson (jmanson@cs.umd.edu)
Date: Wed Sep 17 2003 - 01:10:08 EDT


> I am trying to get an understanding of the subtleties of the Double-Check
> locking problem in Java
>
> Will the following code resolve the problem. If it will not, can somebody
> please explain why not.

I'm afraid not. There is a principle with all of this stuff that the
double-checked locking document doesn't talk about. It boils down to a
single question: when is one thread guaranteed to see writes performed by
another?

The only way to enforce this guarantee is by explicit synchronization.
You can try to play tricks and make an end run around the compiler, but
fundamentally, for the purposes of programming, you should imagine that
each thread in your program will be run on a different planet, and the
only way to guarantee communication between the planets is by explicit
synchronization.

I should note that when I say "explicit synchronization", I don't
necessarily just mean locks. There are a slew of other things that work,
including volatile variables (which are pretty low cost on most systems).

In practice, with your solution, you could easily imagine a compiler
with a perfect understanding of getClass(); it reasons:
  a) instance is initialized when getClass() is called, therefore
  b) "instance.getClass() != null" will always be true, and,
  b.5) there are no other side effects to this call, and thus
  c) you can replace the statement with "initialized = true", and finally
  d) you can move the statement to before the constructor for initialized
        is called, but after the assignment to instance (which has
        already been moved early as per the usual explanation).

Then the reader can see initialized == true and instance != null, and not
see the correctly constructed values of the instance.

But what you have to understand is that there _doesn't even have to be a
optimization you perceive as legitimate_. You could be working with "the
system that decides you will randomly only see half the stuff that goes on
in another thread". Without an explicit, memory-model-sanctioned
mechanism communicating the writes, you are not guaranteed to see them.

Apologies if this is a little rambling; I am a little under the weather.

                                        Jeremy

>
> Thanks in advance for your responses.
>
> Srinivas.
>
> ...
> private static Singleton instance;
> private static Object mutex = new Object();
> private static boolean initialized = false;
>
> private Singleton() {
> }
>
> public static Singleton getInstance() {
> if (instance == null || ! initialized) {
> synchronized(mutex) {
> if (instance == null ) {
> instance = new Singleton();
> initialized = (instance.getClass() != null);
> }
> }
> }
> return instance;
> }
> ...

-------------------------------
JavaMemoryModel mailing list - http://www.cs.umd.edu/~pugh/java/memoryModel



This archive was generated by hypermail 2b29 : Thu Oct 13 2005 - 07:00:51 EDT