Archive

Posts Tagged ‘core java’

Singleton Design Pattern- Java Tech Guy must read!

Singleton design pattern is the first design pattern I learned it many years back. In early days when someone asks me, “do you know any design pattern?” I quickly and promptly answer “I know singleton design pattern” and the question follows, “do you know anything other than singleton” and I stand stumped!

What is Singleton Design Pattern…Have a look on the below image.

Image

A java beginner will know about singleton design pattern. At least he will think that he knows singleton pattern. The definition is even easier than Newton’s third law. Then what is special about the singleton pattern. Is it so simple and straightforward, does it even deserve an article? Do you believe that you know 100% about singleton design pattern? If you believe so and you are a beginner read through the end, there are surprises for you.

There are only two points in the definition of a singleton design pattern,

  1. There should be only one instance allowed for a class and
  2. We should allow global point of access to that single instance.

GOF says, “Ensure a class has only one instance, and provide a global point of access to it.

The key is not the problem and definition. In singleton pattern, trickier part is implementation and management of that single instance. Two points looks very simple, is it so difficult to implement it. Yes it is very difficult to ensure “single instance” rule, given the flexibility of the APIs and many flexible ways available to access an instance. Implementation is very specific to the language you are using. So the security of the single instance is specific to the language used.

Strategy for Singleton instance creation

We suppress the constructor and don’t allow even a single instance for the class. But we declare an attribute for that same class inside and create instance for that and return it. Factory design pattern can be used to create the singleton instance.

public class Singleton {

  private static Singleton singleInstance;

    private Singleton() {}

  public static Singleton getSingleInstance() {

    if (singleInstance == null) {

      synchronized (Singleton.class) {

        if (singleInstance == null) {

          singleInstance = new Singleton();

        }

      }

    }

    return singleInstance;

  }

You need to be careful with multiple threads. If you don’t synchronize the method which is going to return the instance then, there is a possibility of allowing multiple instances in a multi-threaded scenario. Do the synchronization at block level considering the performance issues. In the above example for singleton pattern, you can see that it is thread safe.

But still something is wrong in the above code…keep reading you will get to to know what is wrong in the above code.

Early and lazy instantiation in singleton pattern

The above example code is a sample for lazy instantiation for singleton design pattern. The single instance will be created at the time of first call of the getSingleInstance() method. We can also implement the same singleton design pattern in a simpler way but that would instantiate the single instance early at the time of loading the class. Following example code describes how you can instantiate early. It also takes care of the multithreading scenario.

public class Singleton {

  private static Singleton singleInstance = new Singleton();

  private Singleton() {}

  public  static Singleton getSingleInstance() {

    return singleInstance;

  }

}

Singleton and Serialization

Using serialization, single instance contract of the singleton pattern can be violated. You can serialize and de-serialize and get a new instance of the same singleton class. Using java api, you can implement the below method and override the instance read from the stream. So that you can always ensure that you have single instance.

If you just write…

public class Singleton implements Serializable {

//…

This code becomes ‘broken’ simply by adding one interface implementation. Solution for this is to override the below method:

private Object readResolve() throws ObjectStreamException{

 

}

Case When more than one instance occurs:

Following points we have to take care while creating a singleton pattern:

Case I: Multiple Singletons in Two or More Virtual Machines

When copies of the Singleton class run in multiple VMs, an instance is created for each machine. That each VM can hold its own Singleton might seem obvious but, in distributed systems such as those using EJBs, Jini, and RMI, it’s not so simple. Since intermediate layers can hide the distributed technologies, to tell where an object is really instantiated may be difficult.

Systems based on distributed technologies such as EJB, RMI, and Jini should avoid Singletons that hold state.

Case II: Multiple Singletons Simultaneously Loaded by Different Class Loaders

When two class loaders load a class, you actually have two copies of the class, and each one can have its own Singleton instance. That is particularly relevant in servlets running in certain servlet engines , where each servlet by default uses its own class loader. Two different servlets accessing a joint Singleton will, in fact, get two different objects.

Case III: Singleton Classes Destroyed by Garbage Collection, then Reloaded

When a Singleton class is garbage-collected and then reloaded, a new Singleton instance is created. Any class can be garbage-collected when no other object holds reference to the class or its instances. If no object holds a reference to the Singleton object, then the Singleton class may disappear, later to be reloaded when the Singleton is again needed. In that case, a new Singleton object will be created. Any static or instance fields saved for the object will be lost and reinitialized.

You can avoid class garbage collection in the older VMs by holding a reference to the Singleton class or object in some other object that persists for the program’s life. You can also set your VM to have no class garbage collection

Case IV: Multiple Instances Resulting from Incorrect Synchronization

One of the common Singleton implementations uses lazy initialization of the one instance. That means that the instance is not created when the class loads, but rather when it is first used. (See Listing 2.) A common mistake with that implementation is to neglect synchronization, which can lead to multiple instances of the singleton class.

// error, no synchronization on method
public static Singleton getInstance() {
if (_instance==null) {
_instance = new Singleton();
}

Return  _instance;
}

Two Singletons will be created if the constructor runs and simultaneously another thread call’s the method.

Multiple instances can be created even if you add a synchronized(this) block to the constructor call, as in Listing  below:

// Also an error, synchronization does not prevent
// two calls of constructor.
public static Singleton getInstance() {
if (_instance==null) {
synchronized (Singleton.class) {
_instance = new Singleton();
}
}
return _instance;
}

In the correct solution, seen in Listing below, make getInstance() a synchronized method:

// correct solution
public static synchronized Singleton getInstance() {
// . . .

Double-checked locking is another common solution but, unfortunately, it does not work, see the code below.

// Double-checked locking — don’t use
public static Singleton getInstance() {
if (_instance==null) {
synchronized (Singleton.class) {
if (_instance==null) {
_instance = new Singleton();
}
}
}
}

Case V: Multiple Singletons Arising when Someone has Sub-classed your Singleton

The Singleton Design Pattern is meant to give you control over access to the Singleton class. While I have mostly discussed the control of instantiation, other code can access your class another way: by sub classing it.

The uniqueness of the class cannot be imposed as a compile-time constraint on the subclass unless you use a private constructor. If you want to allow subclassing, for example, you might make the constructor protected. A subclass could then expose a public constructor, allowing anyone to make instances. Since an instance of a subclass is an instance of your superclass, you could find multiple instances of the Singleton.

Case VI: Copies of a Singleton Object that has Undergone Serialization and Deserialization

If you have a serialized object and deserialize it twice in different bjectOutputStreams, or with calls ObjectOutputStream.reset() between deserializations, you get two distinct objects, not two references to the same object.

We already discussed above how to avoid the situation by overriding readResolve();

Case VII: Override the Object clone method to prevent cloning

We can still be able to create a copy of the Object by cloning it using the Object’s clone method. This can be done as shown below

SingletonObjectDemo clonedObject = (SingletonObjectDemo) obj.clone();

This again violates the Singleton Design Pattern’s objective. So to deal with this we need to override the Object’s clone method which throws a CloneNotSupportedException exception.

public Object clone() throws CloneNotSupportedException {

throw new CloneNotSupportedException();

}

The below program shows the final Implementation of Singleton Design Pattern in java, by using all the steps mentioned above.

class SingletonClass {

private static SingletonClass singletonObject;

/** A private Constructor prevents any other class from instantiating.

*/ private SingletonClass() {

// Optional Code }

public static synchronized SingletonClass getSingletonObject() {

if (singletonObject == null) {

singletonObject = new SingletonClass();

} return singletonObject;

}

public Object clone() throws CloneNotSupportedException { throw new CloneNotSupportedException();

}

}

When to use Singleton class?

There is no straightforward answer to this question. A scenario which is acceptable to some will be unacceptable to others.

However, it is commonly accepted that the singleton can yield best results in a situation where various parts of an application concurrently try to access a shared resource. An example of a shared resource would be Logger, Print Spooler, etc.

The following points are suggested to be considered while designing a singleton class:

  1. Singleton classes must be memory-leak free. The instance of the singleton class is to be created once and it remains for the lifetime of the application.
  2. A real singleton class is not easily extensible.
  3. Derive the singleton class from an interface. This helps while doing unit testing (using Dependency Injection).

Don’t forget to add your comments.

 

%d bloggers like this: