Download as doc, pdf, or txt
Download as doc, pdf, or txt
You are on page 1of 6

Simply Singleton

The Singleton pattern can be used for this purpose. This pattern is
effective for limiting the maximum number of instances of a class to
exactly one. In this case, if more than one object needs to use an
instance of the Singleton class, those objects share the same Singleton
class instance. A class that implements the Singleton pattern is called
a Singleton class.

How do you write a Singleton class? Simple: create a public static


method that is solely responsible for creating the single instance of the
class. This also means that the client of the class should not be able to
invoke the Singleton class\'s constructor, either. Because the absence
of a constructor will make the compiler create a no-argument public
constructor, a class applying the Singleton pattern has a private or
protected constructor. Because the constructor is private or protected,
there is no way a client can create an instance of that class by calling
its constructor. The constructor is not accessible from outside of the
class!

Simply Singleton
By: By David Geary
Navigate the deceptively simple Singleton pattern
ometimes it's appropriate to have exactly one instance of a class:
window managers, print spoolers, and filesystems are prototypical
examples. Typically, those types of objects?known as singletons?are
accessed by disparate objects throughout a software system, and
therefore require a global point of access. Of course, just when you're
certain you will never need more than one instance, it's a good bet
you'll change your mind.
The Singleton design pattern addresses all of the previous paragraph's
concerns. With the Singleton design pattern you can:
Ensure that only one instance of a class is created
Provide a global point of access to the object
Allow multiple instances in the future without affecting a singleton
class's clients
Although the Singleton design pattern?as evidenced below by the
figure below?is one of the simplest design patterns, it presents a
number of pitfalls for the unwary Java developer. This article discusses
the Singleton design pattern and addresses those pitfalls.
Note: You can download this article's source code from Resources .
The Singleton pattern
In Design Patterns , the authors describe the Singleton pattern like
this:
Ensure a class has only one instance, and provide a global point of
access to it.
The figure below illustrates the Singleton design pattern class diagram.

Singleton class diagram


As you can see from the figure above, there's not a whole lot to the
Singleton design pattern. Singletons maintain a static reference to the
sole singleton instance and return a reference to that instance from a
static instance() method.
Example 1 shows a classic Singleton design pattern implementation:
Example 1. The classic singleton
public class ClassicSingleton {
private static ClassicSingleton instance = null;
protected ClassicSingleton() {
// Exists only to defeat instantiation.
}
public static ClassicSingleton getInstance() {
if(instance == null) {
instance = new ClassicSingleton();
}
return instance;
}
}
The singleton implemented in Example 1 is easy to understand. The
ClassicSingleton class maintains a static reference to the lone singleton
instance and returns that reference from the static getInstance()
method.
There are several interesting points concerning the ClassicSingleton
class. First, ClassicSingleton employs a technique known as lazy
instantiation to create the singleton; as a result, the singleton instance
is not created until the getInstance() method is called for the first
time. This technique ensures that singleton instances are created only
when needed.
Second, notice that ClassicSingleton implements a protected
constructor so clients cannot instantiate ClassicSingleton instances;
however, you may be surprised to discover that the following code is
perfectly legal:
public class SingletonInstantiator {
public SingletonInstantiator() {
ClassicSingleton instance = ClassicSingleton.getInstance();
ClassicSingleton anotherInstance =
new ClassicSingleton();
...
}
}
How can the class in the preceding code fragment?which does not
extend ClassicSingleton ?create a ClassicSingleton instance if the
ClassicSingleton constructor is protected? The answer is that protected
constructors can be called by subclasses and by other classes in the
same package . Because ClassicSingleton and SingletonInstantiator
are in the same package (the default package), SingletonInstantiator()
methods can create ClassicSingleton instances. This dilemma has two
solutions: You can make the ClassicSingleton constructor private so
that only ClassicSingleton() methods call it; however, that means
ClassicSingleton cannot be subclassed. Sometimes, that is a desirable
solution; if so, it's a good idea to declare your singleton class final ,
which makes that intention explicit and allows the compiler to apply
performance optimizations. The other solution is to put your singleton
class in an explicit package, so classes in other packages (including the
default package) cannot instantiate singleton instances.
A third interesting point about ClassicSingleton : it's possible to have
multiple singleton instances if classes loaded by different classloaders
access a singleton. That scenario is not so far-fetched; for example,
some servlet containers use distinct classloaders for each servlet, so if
two servlets access a singleton, they will each have their own instance.

Fourth, if ClassicSingleton implements the java.io.Serializable


interface, the class's instances can be serialized and deserialized.
However, if you serialize a singleton object and subsequently
deserialize that object more than once, you will have multiple singleton
instances.
Finally, and perhaps most important, Example 1's ClassicSingleton
class is not thread-safe. If two threads?we'll call them Thread 1 and
Thread 2?call ClassicSingleton.getInstance() at the same time, two
ClassicSingleton instances can be created if Thread 1 is preempted just
after it enters the if block and control is subsequently given to Thread
2.
As you can see from the preceding discussion, although the Singleton
pattern is one of the simplest design patterns, implementing it in Java
is anything but simple. The rest of this article addresses Java-specific
considerations for the Singleton pattern, but first let's take a short
detour to see how you can test your singleton classes.
Test singletons
Throughout the rest of this article, I use JUnit in concert with log4j to
test singleton classes. If you are not familiar with JUnit or log4j, see
Resources .
Example 2 lists a JUnit test case that tests Example 1's singleton:
Example 2. A singleton test case
import org.apache.log4j.Logger;
import junit.framework.Assert;
import junit.framework.TestCase;
public class SingletonTest extends TestCase {
private ClassicSingleton sone = null, stwo = null;
private static Logger logger = Logger.getRootLogger();
public SingletonTest(String name) {
super(name);
}
public void setUp() {
logger.info("getting singleton...");
sone = ClassicSingleton.getInstance();
logger.info("...got singleton: " + sone);
logger.info("getting singleton...");
stwo = ClassicSingleton.getInstance();
logger.info("...got singleton: " + stwo);
}
public void testUnique() {
logger.info("checking singletons for equality");
Assert.assertEquals(true, sone == stwo);
}
}
Example 2's test case invokes ClassicSingleton.getInstance() twice and
stores the returned references in member variables. The testUnique()
method checks to see that the references are identical. Example 3
shows that test case output:
Example 3. Test case output
Buildfile: build.xml
init:
[echo] Build 20030414 (14-04-2003 03:08)
compile:
run-test-text:
[java] .INFO main: getting singleton ...
[java] INFO main: created singleton : Singleton@e86f41
[java] INFO main: ...got singleton: Singleton@e86f41
[java] INFO main: getting singleton ...
[java] INFO main: ...got singleton: Singleton@e86f41
[java] INFO main: checking singletons for equality
[java] Time: 0.032
[java] OK (1 test)
As the preceding listing illustrates, Example 2's simple test passes with
flying colors?the two singleton references obtained with
ClassicSingleton.getInstance() are indeed identical; however, those
references were obtained in a single thread. The next section stress-
tests our singleton class with multiple threads.
Multithreading considerations
Example 1's ClassicSingleton.getInstance() method is not thread-safe
because of the following code:
1: if(instance == null) {
2: instance = new Singleton();
3: }
If a thread is preempted at Line 2 before the assignment is made, the
instance member variable will still be null , and another thread can
subsequently enter the if block. In that case, two distinct singleton
instances will be created. Unfortunately, that scenario rarely occurs
and is therefore difficult to produce during testing. To illustrate this
thread Russian roulette, I've forced the issue by reimplementing
Example 1's class. Example 4 shows the revised singleton class:
Example 4. Stack the deck
import org.apache.log4j.Logger;
public class Singleton {
private static Singleton singleton = null;
private static Logger logger = Logger.getRootLogger();
private static boolean firstThread = true;
protected Singleton() {
// Exists only to defeat instantiation.
}
public static Singleton getInstance() {
if(singleton == null) {
simulateRandomActivity();
singleton = new Singleton();
}
logger.info("created singleton: " + singleton);
return singleton;
}
private static void simulateRandomActivity () {
try {
if(firstThread) {
firstThread = false;
logger.info("sleeping...");
// This nap should give the second thread enough time
// to get by the first thread.
Thread.currentThread().sleep(50);
}
}
catch(InterruptedException ex) {
logger.warn("Sleep interrupted");
}
}
}
Example 4's singleton resembles Example 1's class, except the
singleton in the preceding listing stacks the deck to force a
multithreading error. The first time the getInstance() method is called,
the thread that invoked the method sleeps for 50 milliseconds, which
gives another thread time to call getInstance() and create a new
singleton instance. When the sleeping thread awakes, it also creates a
new singleton instance, and we have two singleton instances. Although
Example 4's class is contrived, it stimulates the real-world situation
where the first thread that calls getInstance() gets preempted.
Example 5 tests Example 4's singleton:
Example 5. A test that fails
import org.apache.log4j.Logger;
import junit.framework.Assert;
import junit.framework.TestCase;
public class SingletonTest extends TestCase {
private static Logger logger = Logger.getRootLogger();
private static Singleton singleton = null;
public SingletonTest(String name) {
super(name);
}
public void setUp() {
singleton = null;
}

You might also like