Endless Singleton – Ultimate Info.






The Singleton Pattern

The Singleton Pattern

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.

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:

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

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!

Leave a Reply