Order of static initialisers
Hi all
I've just noticed this interesting behaviour on JSE 1.5.0_06 (Windows) with a singleton class:
publicfinalclass MySingleton{
privatestatic MySingleton instance =new MySingleton();
privatestaticboolean someOtherStuff =false;
publicstatic MySingleton getInstance(){
return instance;
}
}
All fine and well until I have another class that calls getInstance during static initilisation:
public TestClass{
private MySingleton aSingleton = MySingleton.getInstance();//will be null
}
What happens is the MySingleton.getInstance() is run before the private static variables are intialised and hence return null. I didn't expect this as normally I've observed static initialisers to be run in the order they appear in the code. MySingleton works as expected with this test:
public AnotherTestClass{
publicvoid aMethod(){
MySingleton singleton = MySingleton.getInstance();//will be valid instance
}
}
Any thoughts on why this happens and will it be consistent behaviour in future Java releases.
And is this a JVM or a JLS issue?
public TestClass {
private MySingleton aSingleton = MySingleton.getInstance(); //will be null
}
above is not actually static initialization.
but normally we do not use static initialization for singeltons. We create the instance when the getInstance is called for the first time.
Ex:-
public class MySingleton{
MySingleton instance;
public MySingleton getInstance(){
if (instance == null)
instance = new MySingleton();
return instance;
}
}
LRMKa at 2007-7-14 0:33:03 >

I used to initialise singletons in the getInstance method but there is the threat of a thread being pre-empted immediately after executing:
if (instance == null) {
by another thread which then creates the instance and then the original thread gets control again and continues to create a completely new instance - hence we have two threads with two instances of a singleton.
Unlikely in our application (doesn't have too many threads) but I'd still rather avoid it is possible.
you can synchronize getInstance methods so only one thread will get into the method.
I can't reproduce the OP's problem. Does it happen every time, or just occasionally? Using the same JDK.
ejpa at 2007-7-14 0:33:03 >

to continue with this prob, i wrote the following code ....
public final class Singleton {
private static Singleton inst=new Singleton();
private void boo()
{
System.out.print("inside it");
}
public static Singleton get()
{
return inst;
}
public static void main(String[] args) {
Singleton s[]=null;
s[0]=Singleton.get();
s[0].boo();
}
}
and it is giving error null pointer exception at the line
s[0]=Singleton.get();
but if i only declare Singleton s=null ;
and then
s=Singleton.get();
it is working
, why is it so, plz help.
because s[] is null in your first version, so using s[0] causes an NPE.
ejpa at 2007-7-14 0:33:03 >

> you can synchronize getInstance methods so only one> thread will get into the method.doesn't actually work, though[url] http://www.google.com/Top/Computers/Programming/Threads/Java/[/url]
> > you can synchronize getInstance methods so only
> one
> > thread will get into the method.
>
> doesn't actually work, though
>
> [url]http://www.google.com/Top/Computers/Programming/T
> hreads/Java/[/url]
Yes it does work if the whole method is synchronized, that is not double checked locking.
Kaj
true, but synchronizing the whole method can slow things downdoes anyone have the "perfect" singleton implementation?
> true, but synchronizing the whole method can slow> things down> > does anyone have the "perfect" singleton> implementation?Sorry, but the perfect singleton is the one which is fully synchronized :(
> true, but synchronizing the whole method can slow
> things down
>
> does anyone have the "perfect" singleton
> implementation?
I would tend to assume that the class initializer is synchronized anyway (presumably on the Class object). Otherwise a second thread that tried to use a class while the first thread was initializing it would find it incompletely initialized.
The inializer (if you could decompile it) must look something like:
private static __inited;
private synchronized static void <clinit>() {
if(!__inited) {
__inited = true;
// actual initialization
}
}
I don't think there's any way arround synchronization there. In fact I think there's no functional difference between the "lazy" and the "eager" singleton pattern, except that in the eager case, references to any static other than getInstance() would trigger initialization.
but same is the case with Singleton s=null;here also it is null but gets the ref to obj,then why not s[0] gets a reference to the obj
s = Singleton.get() works because you are just reassigning 's'. It is declared, so it exists, and its previous value is of no interest.s[0] = Singleton.get() doesn't work because s[] is declared but null, so s[0]doesn't exist, so you can't assign to it.Ponder on this.
ejpa at 2007-7-14 0:33:04 >
