Java J2EE Portal
Enterprise Java Station
J2EE curve
Java News / Articles
Java News / Articles
Sybase ASE 15 - Data Management Solution
JavaEE Architecture Using The Spring Framework
spring Tutorial
Building Web Applications Using The Spring Framework
Processing...
Buy Java, Deals On Software Technology Store
Click here for great deals on computers, laptops, software and books
Endless Singleton - Ultimate Info. PDF Print
Written by Varun Chopra   
Mar 10, 2005 at 12:41 PM
Sometimes need arises to allow only 1 instance of a class. For e.g. In MS Word we may click ctrl+F n times, but only one search box is opened.

The Singleton Pattern

Similarly Connection Pools, Print Spoolers, Sequences (program equivalent to a database sequence) are other examples. Singleton pattern provides a solution to this requirement. The classic Singleton pattern example:

** Be part of the Best Java Blogger Contest (Feb - Mar 2005)

Note - e.g. is in Java but I have tried to avoid complicated code to make it easily understandable. Also read comments.

public class Singleton

{

 private static Singleton instance = null;//a static reference


//make constructor private so can't be instantiated from outside class

 private Singleton()

 {

 }

 //a public method to return same instance every time

 public static Singleton getInstance()

 {

  if (instance==null)

  {

  instance = new Singleton();//create only first time

  }

  return instance;

 }

 //other public methods

 public void method1()

 {

  //

 }

 

 public void method2()

 {

  //

 }

 //

}

So if I need to get the object of Singleton class (in some other class), I cannot do like this

Singleton s = new Singleton()

because constructor is private. I will have to use following statement

Singleton s = Singleton.getInstance();

which will give me reference to same object every time I execute above statement from different/same classes.

Sub-classing Singleton 

Our purpose was to allow only 1 instance of the class but by making constructor private we have also restricted sub-classing (inheriting) from Singleton. If we want to allow sub-classing we should make constructor protected.

But remember, in Java protected constructor can be executed from outside within the same package. So classes within same package will be able to create any number of instances. Here again,. one solution is to keep singletons in a package explicitly for Singletons.

Static methods versus Singleton

One may see that creating one object seems equivalent to a class having only static methods and calling static methods like ClassName.method().

For e.g.:

public class Singleton

{

 /*

make constructor private so can't be instantiated from outside class

*/

 private Singleton()

 {

 }

 

 //make all methods static

 public static void method1()

 {

  //

 }

 

 public static void method2()

 {

  //

 }

 //

}

We can call methods as Singleton.method1() and Singleton.method2() etc.

In Java java.lang.Math is such a class which is having all methods static.

You can do that also when requirement is of singletons. Decide based on following points;

1. If all your methods are utility methods and are independent of each other, go for static methods

2. If in future you may need to allow more than 1 instances of the class, go for Singleton. Because in this case if you go for static, you will have to change all your calls in different classes from ClassName.method() to object.method().

3. If you want to subclass singleton you should go for singleton class because sub-classing a class with all static methods does not make sense.

Alternative ways to create Singleton 

2 ways we have already seen. I am re-writing the sample code below for all approaches:

a)

public class Singleton

{

 private static Singleton instance = null;//a static reference

 

 //make constructor private so can't be instantiated from outside class

 private Singleton()

 {

 }

 

 //a public method to return same instance every time

 public static Singleton getInstance()

 {

  if (instance==null)

  {

  instance = new Singleton();//create only first time

  }

  return instance;

 }

}

b)

public class Singleton

{

 private static Singleton instance = null;//a static reference

 

 /*

make constructor protected - subclasses and classes in same package can create multiple instances

 */

 protected Singleton()

 {

 }

 

 //a public method to return same instance every time

 public static Singleton getInstance()

 {

  if (instance==null)

  {

  instance = new Singleton();//create only first time

  }

  return instance;

 }

}

c)

public class Pool

{

 static counter = 0;

 public Pool() throws Exception

 {

  if (Pool.counter == 0)

  {

  Pool.counter = 1;

  }

  else

  {

  throws Exception("Only 1 instance possible");

  }

 }

 // we will need a reset method in this case to reset counter to 0

}

d)

public class Singleton

{

 public final static Singleton instance = new Singleton();
//advance instantiation

 

 //make constructor private

 private Singleton()

 {

 }

}

e)

A class with private constructor and all method static - like java.lang.Math in JDK

So we listed 5 approaches. If you have more, please share. 

Loopholes in Singleton approaches

As we saw in case of protected constructor approach, sub-classes and classes within same package can create multiple instances of Singleton. That is a kind of shortcoming of that approach.

Similar problems can occur even in other approaches, as we will see (some of cases explained below may be specific to Java or may vary depending on language and compiler).

We take approach of private constructor:

public class Singleton

{

 private static Singleton instance = null;//a static reference

 

 //make constructor private so can't be instantiated from outside class

 private Singleton()

 {

 }

 

 //a public method to return same instance every time

 public static Singleton getInstance()

 {

  //statement X

  if (instance==null)

  {

  //statement Y

  instance = new Singleton();//create only first time

  }

  return instance;

 }

}

In case this code is used by multiple threads in multi-threaded environment, there are chances of multiple instance creation.

Suppose thread A and thread B both call getInstance method(). Thread A's time slice ends after execution of statement X (see comments) but before execution of statement Y. Now thread B starts execution. It passes the check at statement X because instance is still null and it gets an instantiated object of Singleton at statement Y. After completion of thread B, A starts execution again at statement Y. It will also get a different instance.

So we have 2 instances of Singleton. That's bad isn't it?

Solution - Synchronize getInstance() so that it can be called (& completed) by only 1 thread at a time

public class Singleton

{

 private static Singleton instance = null;//a static reference

 

 //make constructor private so can't be instantiated from outside class

 private Singleton()

 {

 }

 

 //a public method to return same instance every time

 public synchronized static Singleton getInstance()

 {

  //statement X

  if (instance==null)

  {

  //statement Y

  instance = new Singleton();
//create it only first time

  }

  return instance;

 }

}

We found a good solution and it is reliable too. But if you look at the code carefully, you will notice that synchronization is required only the first time (when the instance needs to be created). After that synchronization is not required because statement X will always return false. So above code is reliable but it unnecessarily synchronizes the code every time, hence affects the performance in multithreaded environment.

Solution is to synchronize the statement that instantiates the object as below:

public class Singleton

{

 private static Singleton instance = null;//a static reference

 

 //make constructor private so can't be instantiated from outside class

 private Singleton()

 {

 }

 

 //a public method to return same instance every time

 public static Singleton getInstance()

 {

  //statement X

  if (instance==null)

  {

  Synchronized(Singleton.class)

  {

   //statement Y

   instance = new Singleton();//create it only first time

  }

  }

  return instance;

 }

}

It looks better but actually does not work. Because similar to first

scenario if thread A is preempted after execution of statement X, B will start and get an instance of its own. When A will resume from

synchronized block, it will get a different instance.

One solution that comes to mind of above problem is to check instance again before executing statement Y. It is called double check locking ? see below:

public class Singleton

{

 private static Singleton instance = null;//a static reference

 

 //make constructor private so can't be instantiated from outside class

 private Singleton()

 {

 }

 

 //a public method to return same instance every time

 public static Singleton getInstance()

 {

  //statement X

  if (instance==null)

  {

  Synchronized(Singleton.class)

  {

   //statement X.1

   if (instance==null)

   {

   //statement Y

   instance = new Singleton();//create it only first time

   }

  }

  }

  return instance;

 }

}

Now situation improves. Suppose thread A stops after statement X. B will go inside, will get an instance. A will start again, but at statement X.1 check will fail and duplicate instance won't be created. Doesn't that look good and optimized (but code is getting cluttered - I told you at the start, it is not easy to write Singleton classes).

UNFORTUNATELY, above code also doesn't work always (at least in Java). This is because object creation in Java is a 2-step process

step 1 - allocate a reference (address) of class to variable

step 2 - execute constructor to create object in memory and make variable of step 1 point to this object

i.e. on statement instance = new Singleton()

step 1 allocate reference of Singleton class to instance variable - say at memory location 100 (so now instance points to valid but partial Singleton object whose constructor is yet to execute)

step 2 execute constructor of Singleton to create object ((say at memory location 1000) and make instance point to this object, so now instance will point to 1000

Now keep these 2 steps in mind and go through following steps

1. Thread A starts execution, goes in to Synchronized block, reaches statement Y

2. statement Y starts execution - step 1 of instantiation is complete but before step 2 of instantiation, thread is preempted by thread B

3. Thread B start execution at statement X, but this check fails because reference is already assigned to instance and is non-null, so it returns this PARTIALLY CREATED instance (that points to location 100)

4. Thread A resumes execution and completes step 2 of instantiation (now point to location 1000) and returns it...so a different object that points to location 1000

That's sad...so much effort and still no certainty.

There are 2 approaches though which are thread-safe (of course you have to pay for that in some way)

1) Synchronize getInstance() method

2) Use advance instantiation approach - It is thread-safe

public class Singleton

{

 public final static Singleton instance = new Singleton();//advance instantiation

 //make constructor private

 private Singleton()

 {

 }

}
 

use it like

Singleton sobj = Singleton.instance;

sobj.method1();

....

And you know, static variables are initialized when they are used first time. So we have on-demand instantiation (not advanced) in above code. Great news, isn't that.

Price of this is if you want to allow more than 1 instance of above class later, you can't do that though.

Other Issues

Ahh! Singleton took a lot of time. I never expected this from it. There could be other issues, which I will just list here. All these issues are specific to Java.

1. In case of distributed systems (in EJBs for e.g.) multiple JVMs may be operating at different layers, and each JVM will create its own instance of Singleton - hence multiple instances can be there.

2. Different class loaders will create different instances of Singleton.

This is particularly relevant to Servlets (in iPlanet for e.g.) where each servlet by default uses its own class loader.

3. In case a singleton object was created at some moment but all its clients have completed execution (so no client points to it), object is garbage collected. Then new client will get a new instance of the Singleton. This can be problematic when new client expects some values set by previous clients.

4. Serialization and then deserialization multiple times will give multiple objects of Singleton

Hope you find this information useful.

regards

Varun


User Comments

Comment by nilesh on 2005-03-10 14:37:16
hi Varun 
Varun U have realy Donr .[B]Great Job... [/B] but the Best Way which i feel is like that .. its Some thing like ur [U]double check locking[/U] but slightly Diffrent .... 
class Singleton  

private static Singleton instance = null; 
private static Object lockObject = new Object(); 
public static Singleton getInstance() 

if(instance == null) 

synchronized(lockObject) 

if(instance == null) 

instance = new Singleton (); 



return instance; 
}  

 
i hope this Want reduse ur Performanse and Woked in all case ... i have implimented this way .... its working fine ...... but if u found any Problem just Let me Know ... 
Regards  
Nilesh Mishra

Comment by varun077 on 2005-03-10 15:44:49
Hi Nilesh, 
 
Thankls for going thru this. 
What you suggested is exactly similar to double check locking and is  
prone to same problems.  
You have used an explicit lockObject for locking while I have  
used the public static field provided by Java itself [I](myClass.class)[/I]. 
 
regards 
Varun 
 

Comment by Guest on 2005-04-21 01:00:00
//statement X 
if (instance==null) { 
 
synchronized (Singleton.class) { 
//statement X.1 
if (instance==null) { 
//statement Y 
Singleton i = new Singleton();//create it only first time 
instance = i; 



 
// above should work, since allocation and 
// initialization should be complete when 
// instance is assigned - dan 
 
 

Comment by Guest on 2005-05-04 23:28:39
Varun is right on point when he states that there are only two thread safe ways to implement a singleton. Dan, in your example you overlook the possibility of the compiler optimizing away the temp variable and inlining the byte code instruction. Many people have tried many different approaches at what you're trying but compiler optimizations and instruction re-ordering make it impossible to do anything short of a full method lock. See the original JavaWorld article for details. 
 
Cliff 
8)

Comment by Surender on 2008-07-29 07:16:16
Okay, my concern is at stmt Y: 
 
Synchronized(Singleton.class) 
 

 
//statement X.1 
 
if (instance==null) 
 

 
//statement Y 
 
instance = new Singleton();//create it only first time 
 

 

 
When Y executes it is actually 3 step execution: allocateMemory(), assign the memory location to 'instance' reference and then invocation of constructor to initialize the values in the memory created.  
Irrespective of our understanding, thing is be it 2 or 3 step, the steps would still be within the synchronized block and executed; further even if that thread is pre-empted the new thread can't do anything since the previous thread hasn't given up the lock. The previous thread would come out of the synchronized block only after all those steps involved are executed.  
Unless, the object creation happens somewhere and sometime else and the executing thread is satisfied on reference assignment alone I'm not convinced. 
Can you explain?
Your Name / Email Address
Comment
Spam Protection - Please enter the code in the image -

Listen to code


Add This Feed Button

Enter your Email


Java Expert Interviews
Jesper_Joergensen
WebLogic 9.0 takes J2EE to a new level of reliability and scalability
JavaFX Expert
JavaFX Is Many Times Faster And Easier Than Swing
Sameer Tyagi Sun
Understanding Web Services and SOA
Processing...
Go to top of page  Home |
SiteMap

Copyright 2004 to 2008 Rightrix Solutions. All rights reserved. All product names are trademarks of their respective companies. Java and all Java-based marks are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States and other countries. Rightrix Solutions and IndicThreads.com are independent of Sun Microsystems, Inc.

Views expressed at IndicThreads.com reflect the views of the authors alone, and do not necessarily reflect those of IndicThreads.com. IndicThreads.com and it's authors are not responsible for reader comments and opinions.

Enterprise Java J2EE JEE Portal >> IndicThreads.com