Endless Singleton – Ultimate Info.

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

The following two tabs change content below.
Content Team

Content Team

The IndicThreads Content Team posts news about the latest and greatest in software development as well as content from IndicThreads' conferences and events. Track us social media @IndicThreads. Stay tuned!
Content Team

Content Team

The IndicThreads Content Team posts news about the latest and greatest in software development as well as content from IndicThreads' conferences and events. Track us social media @IndicThreads. Stay tuned!

  • Surender

    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?

  • maheshr29@gmail.com

    The Book for servlets and Jsp

  • Guest

    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)

  • Guest

    //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

  • varun077

    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

  • nilesh

    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