[Mono-list] Class library developers: locking issues to keep in mind

Alexander Klyubin klyubin@aqris.com
Mon, 29 Oct 2001 15:50:35 +0200


Just browsed Joshua Bloch's Effective Java (ISBN: 0201310058). He also 
states that DCL is broken in Java. As one of the solutions in item #48 
initialize-on-demand holder class idiom is proposed. Applied to our 
situation it looks like this:

class Singleton {
   private static class SingletonHolder {
     static final Singleton singleton = new Singleton();
   }

   public static Singleton GetHeavyObject() {
     return SingletonHolder.singleton;
   }
}

It uses Java's feature that class (SingletonHolder) is not initialized 
until it is first used. What this essentially means is that new 
Singleton() will be executed on first invocation of GetHeavyObject, not 
earlier.

Alexander Klyubin

Serge wrote:

>>Now, what happens is that this
>>thread does NOT perform an explicit read barrier
>>and hence may end up
>>with incompletely initialized singleton instance.
>>
> 
> Well, I see your point.
> This situation is possible when JIT inlines constructor's body and reorders
> instructions so that object reference is non-null before constructors body
> is executed;
> Well, under .NET we could ensure valid execution sequence by disabling
> inlining and using Create helper as I described in previous posts.
> Hmm, it seems using volatile is ineffective here.
> But I think applying the following patches should help (see previous post):
> 1) Extra check in the getter after initializer;
> 2) Extra thread fork/join in RealInit (all memory will be flushed upon
> termination);
> 3) Using non-inlined helper to create singleton;
> To ensure singleton and initializer will be created in the correct order we
> could use dummy check for non-null value returned by helper, such as:
>    if (singleton == null) {
>       singleton = Create ();
> 
>       // This dummy check ensures that JIT
>       // won't place initializer's constructor
>       // before singleton creation
>       if (singleton != null)
>          initializer = new Call (DummyInit);
>    }
> Perhaps it's also needed to move DummyInit creation into non-inlined helper.
> The above fix will ensure that singleton will be only visible when it's
> fully constructed;
> This still implies that RealInit could be called more than once, but at
> least for any given thread it's guaranteed to be called only once.
> 
> As for Java, there is no way to explicitly disable inlining, right?
> So perhaps, for Java it's just as hopelessly broken as DCL.
> Maybe spawing separate thread for the helper will help?
> 
> What do you think?
> 
> Sergey
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> _______________________________________________
> Mono-list maillist  -  Mono-list@ximian.com
> http://lists.ximian.com/mailman/listinfo/mono-list
>