With option 2, if instance has been created, no lock is required : the code seems to be more efficient.
First, synchronization is now much more efficient. I would not worry about it too much anymore.
Second, while the code in option 2 will work in getting you a singleton, there is no guarantee that "if instance has been created, no lock is required". The reason is because the compiler will detect the common condition, and optimize it by moving the outer loop into the synchronization block. Search "double checked locking" for more information.
How to choose between writing a synchronized method or a synchronized block?
A synchronized method syncs on the object instance that is running the method. This may not be the right level of granularity for some problems. It may block other threads for longer than really necessary. Static methods have no "this" and lock on the class which is even larger granularity.
A synchronized block specifies what object we lock on, so it can use "this" or any other object that happens to be shared by multiple threads, including a static variable shared by all instances of the class. We can have a short synchronized block in the middle of a long running method and only lock for that short amount of time.
At a rather deep theoretical level a synchronized method is leaky encapsulation because it "exposes the monitor" which bothers some people a lot more than it does me.
Any of those notions help?
A good question is never answered. It is not a bolt to be tightened into place but a seed to be planted and to bear more seed toward the hope of greening the landscape of the idea. John Ciardi
Joined: Sep 28, 2005
Well, you confirm that optimizing is a diffucult thing for developers...
And I'm affraid that some commercial products implements Singleton pattern with "option 2"...
Option 2 is totally broken. Optimizing JVMs can set the reference before they finish creating the objects. Some question about if this is legal or not, but be careful. DCL is broken period, its not really a java issue, the theory behind it is flawed.
Never use synchronized methods, they expose the monitor object to the public. Violating encapsulation in the worse way. For a good example see the insides of Thread.join();
The instancee will be created when the class is loaded. Supposedly this works. Makes you wonder though why there is a difference between class loading and instance creating...
Joined: Jan 29, 2003
Hmmm, we called exactly the same thing lazy and not lazy. By lazy I meant not created until you ask for it. With this static variable it will be created when the class is loaded, which could be triggered by Class.forName() or calls to other static methods. In real practice, referencing the class and asking for an instance is probably the same line of code so it matters darned little.
BTW: This is the simplest form I can think of for this, but not the only one. You could implement Singleton in several other interesting ways.
Joined: Oct 06, 2005
Sometimes you hang on the lazy way, because the singleton needs some other things that won't be available until other constructors have be done.
Joined: Jan 29, 2003
I can't think of a requirement to defer construction of the single instance until the class has done some other initialization. Or at least one I couldn't make go away. That would force users to do something like:
What are the chances one client would forget to do that? [ October 14, 2005: Message edited by: Stan James ]