Singleton Pattern

Its one of the simplest design pattern in Java.

If any one asks me which design pattern you are good then I would proudly say Singleton.

But when they ask in depth concept of singleton then I get stumped.

Is it really singleton is that much difficult ?

Really not but it has many scenarios that we need to understand especially beginners.

Definition :
There should be only one instance allowed for the class in all the situation and we should provide global point of access to that instance.
Definition is as easy as 1,2,3 and A,B,C,D.

Lets see how can we implement Singleton Class.

How can we ensure object should be only one all the time ?
Hint : put object creation logic in only one place and don’t allow users to execute this logic every time they try to but allow only once.

Object creation logic -> what it is

How we create object in Java ?

Yes using constructor , and we should not allow users to access constructor and execute it every time they try to.
But we should do it one time to get one object at least.
So how can we ensure constructor is accessible and executable only once ?

1) Prevent constructor access outside the class so that no outsiders can be able to create an instance.
How to make it -> how to prevent method access outside class ?
Simple make method as private right, similarly make constructor as private.

2) Prevent constructor execution inside the class more than once.
How to make it -> this has many ways to implement, lets see it with example.
If above 2 conditions are satisfied then we will have always one object for our class.
And that class is called as Singleton as it produces single object all the time we request.

No much theory , we will start the implementing it now
Many Ways of creating singleton object are available

Approach 1

Eager initialization or initialize before use

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package com.kb.singleton;
 
public class EagerSingletonClass {
    private static volatile EagerSingletonClass singletonInstance = new EagerSingletonClass();
    
    //making constructor as private to prevent access to outsiders
    private EagerSingletonClass() {
        
    }
    
    public static EagerSingletonClass getInstance(){
        return singletonInstance;
    }
 
}
package com.kb.singleton;

public class EagerSingletonClass {
	private static volatile EagerSingletonClass singletonInstance = new EagerSingletonClass();
	
	//making constructor as private to prevent access to outsiders
	private EagerSingletonClass() {
		
	}
	
	public static EagerSingletonClass getInstance(){
		return singletonInstance;
	}

}

The instance of EagerSingletonClass is created at the startup of the class.
Since it’s a static, it gets loaded and created during loading of the EagerSingletonClass.

Junit test class for the above class to test singleton.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package com.kb.singleton;
 
import static org.junit.Assert.*;
 
import org.junit.Test;
 
public class EagerSingletonClassTest {
 
    @Test
    public void testSingleton() {
        
        EagerSingletonClass instance1 = EagerSingletonClass.getInstance();
        EagerSingletonClass instance2 = EagerSingletonClass.getInstance();
        System.out.println("checking singleton objects equality");
        assertEquals(true, instance1==instance2);
        
    }
 
}
package com.kb.singleton;

import static org.junit.Assert.*;

import org.junit.Test;

public class EagerSingletonClassTest {

	@Test
	public void testSingleton() {
		
		EagerSingletonClass instance1 = EagerSingletonClass.getInstance();
		EagerSingletonClass instance2 = EagerSingletonClass.getInstance();
		System.out.println("checking singleton objects equality");
		assertEquals(true, instance1==instance2);
		
	}

}

Advantage : This strategy creates the object during the loading of the class and hence its faster and safer from multithreading scenario. Only thing we have to make instance as volatile for handling multi threading scenario.
Disadvantage : This strategy creates the instance during class loading itself, hence if we don’t use it then it’s a waste of whole time and memory taken to create the instance.
So better to go for a strategy to create an instance as and when we require it.

When to use above strategy?
Whenever we are 100% sure that object is definitely used in our application.
OR
When the object is not heavy also its ok we can manage speed and memory.

Approach 2

Lazy initialization or initialize as and when we need

Instead of creating an object at the startup, it’s good to create an object as and when it is required.
So let’s see how can we do that

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package com.kb.singleton;
 
public class LazySingleton {
    private static volatile LazySingleton singletonInstance = null;
    
    //making constructor as private to prevent access to outsiders
    private LazySingleton() {
        
    }
    
    public static LazySingleton getInstance(){
        if(singletonInstance==null){
            synchronized (LazySingleton.class) {
                singletonInstance = new LazySingleton();
            }
        }
        return singletonInstance;
    }
 
 
 
}
package com.kb.singleton;

public class LazySingleton {
	private static volatile LazySingleton singletonInstance = null;
	
	//making constructor as private to prevent access to outsiders
	private LazySingleton() {
		
	}
	
	public static LazySingleton getInstance(){
		if(singletonInstance==null){
			synchronized (LazySingleton.class) {
				singletonInstance = new LazySingleton();
			}
		}
		return singletonInstance;
	}



}

In the above program, we have created an object only when there is a request through getInstance() method.

Here during the first invocation of getInstance(), the object ‘singletonInstance’ will be null and it executes the if condition block as it becomes true and creates an object.

Then subsequent calls to getInstance() method will return the same object .

But if we look at the multithreading scenario , problem comes when below context comes
2 threads t1 and t2 calls getInstance() method and thread t1 executes

if(singletonInstance==null) and finds singletonInstance as null so it enters the synchronized block to create an object. But before it executes the object creation logic if thread t2 executes if(singletonInstance==null) then it will also find singletonInstance as null so it will also try to enter synchronized block but it will not have a lock as the first thread t1 already entered so thread t2 waits for the thread t1 to complete the execution of synchronized block.
Hence thread t1 executes and creates the object . now thread t2 also enters the synchronized block as it was waiting for the synchronized block and creates the object once again.
So two objects are created by 2 threads. So fails to achieve singleton.

Solution to the above problem is Double Checked Locking
It says re check the instance variable again inside the synchronized block before we execute the logic of object creation inside synchronized block.

So this way we can avoid the creation of object more than once by multiple threads.
How ?

Thread t1 checks the condition if(singletonInstance==null) and it is true for first time so it enters synchronized block and there again it checks the condition if(singletonInstance==null) and this is also true so creates the object.

Now thread t2 enters the method getInstance() and assume it has executed if(singletonInstance==null) condition before the thread t1 executes the object creation logic then t2 also waits to enter the synchronized block.

After thread t1 comes out of synchronized block thread t2 enters the same block but we have again the if condition there if(singletonInstance==null) but thread t1 already created an object it makes the condition to be false and stop the execution further and returns the same instance.

Lets see how it can be done in code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package com.kb.singleton;
 
public class LazySingletonDoubleLockCheck {
 
    private static volatile LazySingletonDoubleLockCheck singletonInstance = null;
    
    //making constructor as private to prevent access to outsiders
    private LazySingletonDoubleLockCheck() {
        
    }
    
    public static LazySingletonDoubleLockCheck getInstance(){
        if(singletonInstance==null){
            synchronized (LazySingleton.class) {
                if(singletonInstance ==null){
                singletonInstance = new LazySingletonDoubleLockCheck();
                }
            }
        }
        return singletonInstance;
    }
}
package com.kb.singleton;

public class LazySingletonDoubleLockCheck {

	private static volatile LazySingletonDoubleLockCheck singletonInstance = null;
	
	//making constructor as private to prevent access to outsiders
	private LazySingletonDoubleLockCheck() {
		
	}
	
	public static LazySingletonDoubleLockCheck getInstance(){
		if(singletonInstance==null){
			synchronized (LazySingleton.class) {
				if(singletonInstance ==null){
				singletonInstance = new LazySingletonDoubleLockCheck();
				}
			}
		}
		return singletonInstance;
	}
}

Lets do the unit testing

package com.kb.singleton;

import static org.junit.Assert.*;

import org.junit.Test;

public class LazySingletonDoubleLockCheckTest {

@Test
public void testSingleton() {

LazySingletonDoubleLockCheck instance1 = LazySingletonDoubleLockCheck.getInstance();
LazySingletonDoubleLockCheck instance2 = LazySingletonDoubleLockCheck.getInstance();
System.out.println(“checking singleton objects equality”);
assertEquals(true, instance1==instance2);
//fail(“Not yet implemented”);
}

}

The above implementation is the best advisable solution for singleton pattern which is best suitable for all scenarios like single threaded, multithreaded.

Approach 3

Singleton using Inner class
Lets see the below code of creating object using inner class

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package com.kb.singleton;
 
public class SingletonUsingInnerClass {
    
    private SingletonUsingInnerClass() {
        
    }
    
    private static class LazySingleton{
        private static final SingletonUsingInnerClass  SINGLETONINSTANCE = new SingletonUsingInnerClass();
    }
    
    public static SingletonUsingInnerClass getInstance(){
        return LazySingleton.SINGLETONINSTANCE;
    }
    
 
}
package com.kb.singleton;

public class SingletonUsingInnerClass {
	
	private SingletonUsingInnerClass() {
		
	}
	
	private static class LazySingleton{
		private static final SingletonUsingInnerClass  SINGLETONINSTANCE = new SingletonUsingInnerClass();
	}
	
	public static SingletonUsingInnerClass getInstance(){
		return LazySingleton.SINGLETONINSTANCE;
	}
	

}

Unit test code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package com.kb.singleton;
 
import static org.junit.Assert.*;
 
import org.junit.Test;
 
public class SingletonUsingInnerClassTest {
 
    @Test
    public void testSingleton() {
        
        SingletonUsingInnerClass instance1 = SingletonUsingInnerClass.getInstance();
        SingletonUsingInnerClass instance2 = SingletonUsingInnerClass.getInstance();
        System.out.println("checking singleton objects equality");
        assertEquals(true, instance1==instance2);
    }
 
}
package com.kb.singleton;

import static org.junit.Assert.*;

import org.junit.Test;

public class SingletonUsingInnerClassTest {

	@Test
	public void testSingleton() {
		
		SingletonUsingInnerClass instance1 = SingletonUsingInnerClass.getInstance();
		SingletonUsingInnerClass instance2 = SingletonUsingInnerClass.getInstance();
		System.out.println("checking singleton objects equality");
		assertEquals(true, instance1==instance2);
	}

}

The above approach of creating object using inner class is one of the best approach to create singleton object.
Here unless and until someone tries to access the static reference variable of LazySingleton static inner class, the object will not be created.
So this will also ensure the creation of object as and when it is required.
And it is very simple to implement. It is also safe from multi threading.

Approach 4
Singleton with serialization and de serialization

Now assume our application is distributed and we serialize our singleton object and write it to file.
Later we read it by de serializing the singleton object.

De serializing the object always creates a new object with the state available inside the file.

If we do any state change after writing to a file and then try to de serialize the object , we will get original object not new state object. So we got 2 objects in this process.

Lets try to understand this problem by program

First thing -> make the singleton class serializable to serialize and deserialize this class’s object.
Second thing -> write the object to file(serialization)
Third thing -> change the object state
Fourth thing -> de serialize the object

Our singleton class is as below

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package com.kb.singleton;
 
import java.io.Serializable;
 
public class SingletonSerializeAndDesrialize implements Serializable {
    
    private int x=100;
    
    private static volatile SingletonSerializeAndDesrialize singletonInstance = new SingletonSerializeAndDesrialize();
 
    private SingletonSerializeAndDesrialize() {
 
    }
 
    public static SingletonSerializeAndDesrialize getInstance() {
        return singletonInstance;
    }
 
    public int getX() {
        return x;
    }
 
    public void setX(int x) {
        this.x = x;
    }
 
}
package com.kb.singleton;

import java.io.Serializable;

public class SingletonSerializeAndDesrialize implements Serializable {
	
	private int x=100;
	
	private static volatile SingletonSerializeAndDesrialize singletonInstance = new SingletonSerializeAndDesrialize();

	private SingletonSerializeAndDesrialize() {

	}

	public static SingletonSerializeAndDesrialize getInstance() {
		return singletonInstance;
	}

	public int getX() {
		return x;
	}

	public void setX(int x) {
		this.x = x;
	}

}

Serialize our object then do some change in the state and then de serialize it.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
package com.kb.singleton;
 
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
 
public class SerializeAndDeserializeTest {
 
    static SingletonSerializeAndDesrialize instanceOne = SingletonSerializeAndDesrialize.getInstance();
 
    public static void main(String[] args) {
        try {
            // Serialize to a file
            
            ObjectOutput out = new ObjectOutputStream(new FileOutputStream(
                    "filename.ser"));
            out.writeObject(instanceOne);
            out.close();
 
            instanceOne.setX(200);
 
            // Serialize to a file
            ObjectInput in = new ObjectInputStream(new FileInputStream(
                    "filename.ser"));
            SingletonSerializeAndDesrialize instanceTwo = (SingletonSerializeAndDesrialize) in.readObject();
            in.close();
 
            System.out.println(instanceOne.getX());
            System.out.println(instanceTwo.getX());
 
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }}
package com.kb.singleton;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;

public class SerializeAndDeserializeTest {

	static SingletonSerializeAndDesrialize instanceOne = SingletonSerializeAndDesrialize.getInstance();

	public static void main(String[] args) {
		try {
			// Serialize to a file
			
			ObjectOutput out = new ObjectOutputStream(new FileOutputStream(
					"filename.ser"));
			out.writeObject(instanceOne);
			out.close();

			instanceOne.setX(200);

			// Serialize to a file
			ObjectInput in = new ObjectInputStream(new FileInputStream(
					"filename.ser"));
			SingletonSerializeAndDesrialize instanceTwo = (SingletonSerializeAndDesrialize) in.readObject();
			in.close();

			System.out.println(instanceOne.getX());
			System.out.println(instanceTwo.getX());

		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}}

Output

It clearly says we have 2 distinct objects even though its singleton.
This is happening because de serialization creates new instance with the state available in the file.

How to overcome this problem means how to prevent creating new instance during de serialization?
Solution is very simple – implement below method in your singleton class

1
2
Access_modifier  Object readResolve() throws ObjectStreamException{
}
Access_modifier  Object readResolve() throws ObjectStreamException{
}

Example

1
2
3
Public Object readResolve() throws ObjectStreamException{
return modifiedInstance;
}
Public Object readResolve() throws ObjectStreamException{
return modifiedInstance;
}

Apply this to above singleton class, then complete singleton class is as below

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package com.kb.singleton;
 
import java.io.ObjectStreamException;
import java.io.Serializable;
 
public class SingletonSerializeAndDesrialize implements Serializable {
    
    private int x=100;
    
    private static volatile SingletonSerializeAndDesrialize singletonInstance = new SingletonSerializeAndDesrialize();
 
    private SingletonSerializeAndDesrialize() {
     System.out.println("inside constructor");
    }
 
    public static SingletonSerializeAndDesrialize getInstance() {
        return singletonInstance;
    }
 
    public int getX() {
        return x;
    }
 
    public void setX(int x) {
        this.x = x;
    }
    
    public Object readResolve() throws ObjectStreamException{
        return singletonInstance;
        }
 
 
}
package com.kb.singleton;

import java.io.ObjectStreamException;
import java.io.Serializable;

public class SingletonSerializeAndDesrialize implements Serializable {
	
	private int x=100;
	
	private static volatile SingletonSerializeAndDesrialize singletonInstance = new SingletonSerializeAndDesrialize();

	private SingletonSerializeAndDesrialize() {
     System.out.println("inside constructor");
	}

	public static SingletonSerializeAndDesrialize getInstance() {
		return singletonInstance;
	}

	public int getX() {
		return x;
	}

	public void setX(int x) {
		this.x = x;
	}
	
	public Object readResolve() throws ObjectStreamException{
		return singletonInstance;
		}


}

Now run our above serialize and deserialize class to check the output for both the instances
Output

This is because, during de serialization it calls readResolve() method and there we are returning the existing instance which prevents creating new instance and ensures singleton object.

Serial version id

Whenever the class structure gets change after we serialize and before we de serialize it.

Then during de serialization process , it finds an compatible class and hence throws an exception
java.io.InvalidClassException: SingletonClass; local class incompatible: stream classdesc serialVersionUID = 5026910492258526905, local class serialVersionUID = 3597984220566440782

so to avoid this exception we have to use serial version id to the serializable class always.
And its syntax is as below

private static final long serialVersionUID = 1L;

so finally by covering all the above scenario, the best possible solution of singleton class is

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package com.kb.singleton;
 
import java.io.Serializable;
 
 
public class FinalSingleton implements Serializable{
     private static final long serialVersionUID = 1L;
    
    private FinalSingleton() {
        
    }
    
    private static class LazyLoadFinalSingleton{
        private static final FinalSingleton  SINGLETONINSTANCE = new FinalSingleton();
    }
    
    public static FinalSingleton getInstance(){
        return LazyLoadFinalSingleton.SINGLETONINSTANCE;
    }
    
    private Object readResolve() {
        return getInstance();
    }
 
 
}
package com.kb.singleton;

import java.io.Serializable;


public class FinalSingleton implements Serializable{
	 private static final long serialVersionUID = 1L;
	
	private FinalSingleton() {
		
	}
	
	private static class LazyLoadFinalSingleton{
		private static final FinalSingleton  SINGLETONINSTANCE = new FinalSingleton();
	}
	
	public static FinalSingleton getInstance(){
		return LazyLoadFinalSingleton.SINGLETONINSTANCE;
	}
	
	private Object readResolve() {
        return getInstance();
    }


}

About the Author

Karibasappa G C (KB)
Founder of javainsimpleway.com
I love Java and open source technologies and very much passionate about software development.
I like to share my knowledge with others especially on technology 🙂
I have given all the examples as simple as possible to understand for the beginners.
All the code posted on my blog is developed,compiled and tested in my development environment.
If you find any mistakes or bugs, Please drop an email to kb.knowledge.sharing@gmail.com

Connect with me on Facebook for more updates

Share this article on