Skip to content

Singleton java

Examples of DIFFERENT Singleton Design Pattern

Eager Initialization

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
package edu.redwoods.singleton;

public class EagerInitializedSingleton {

    private static final EagerInitializedSingleton instance = new EagerInitializedSingleton();

    // private constructor to avoid client applications using the constructor
    private EagerInitializedSingleton(){}

    public static EagerInitializedSingleton getInstance() {
        return instance;
    }
}

Pros

  • Useful if Singleton utilizes minimal resources.

Cons

  • Object is created even if client doesn’t use it.
  • No ability to handle exceptions.
  • Reflection can destroy this Singleton implementation.

Static Block Initialization

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
package edu.redwoods.singleton;

public class StaticBlockSingleton {

    private static StaticBlockSingleton instance;

    private StaticBlockSingleton(){}

    // static block initialization for exception handling
    static {
        try {
            instance = new StaticBlockSingleton();
        } catch (Exception e) {
            throw new RuntimeException("Exception occurred in creating singleton instance");
        }
    }

    public static StaticBlockSingleton getInstance() {
        return instance;
    }
}

Pros

  • Useful if Singleton utilizes minimal resources.
  • Allows for exception handling.

Cons

  • Object is created even if client doesn’t use it.
  • Reflection can destroy this Singleton implementation.

Lazy Initialization

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
package edu.redwoods.singleton;

public class LazyInitializedSingleton {

    private static LazyInitializedSingleton instance;

    private LazyInitializedSingleton(){}

    public static LazyInitializedSingleton getInstance() {
        if (instance == null) {
            instance = new LazyInitializedSingleton();
        }
        return instance;
    }
}

Pros

  • Initialized only when needed.
  • Allows for exception handling.

Cons

  • Not Thread-safe (i.e. would fail in multi-threaded code).
  • Reflection can destroy this Singleton implementation.

Thread-Safe Lazy Singleton

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
package edu.redwoods.singleton;

public class ThreadSafeSingleton {

    private static ThreadSafeSingleton instance;

    private ThreadSafeSingleton(){}

    public static synchronized ThreadSafeSingleton getInstance() {
        if (instance == null) {
            instance = new ThreadSafeSingleton();
        }
        return instance;
    }

}

Pros

  • Initialized only when needed.
  • Allows for exception handling.
  • Thread-Safe

Cons

  • Reduced performance in synchronization.
  • Fails in Java 5 in certain scenarios where too many threads tried to get the instance of the singleton class simultaneously due to OLD Java memory model.
  • Reflection can destroy this Singleton implementation.

Thread-Safe Lazy Double-Checked Locking Singleton

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
package edu.redwoods.singleton;

public class ThreadSafeSingleton {

    private static ThreadSafeSingleton instance;

    private ThreadSafeSingleton(){}

    public static ThreadSafeSingleton getInstance() {
        if (instance == null) {
            synchronized (ThreadSafeSingleton.class) {
                if (instance == null) {
                    instance = new ThreadSafeSingleton();
                }
            }
        }
        return instance;
    }

}

Pros

  • Initialized only when needed.
  • Allows for exception handling.
  • Thread-Safe

Cons

  • Fails in Java 5 in certain scenarios where too many threads tried to get the instance of the singleton class simultaneously due to OLD Java memory model.
  • Reflection can destroy this Singleton implementation.

Bill Pugh Singleton Implementation

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
package edu.redwoods.singleton;

public class BillPughSingleton {

    private BillPughSingleton(){}

    private static class SingletonHelper {
        private static final BillPughSingleton INSTANCE = new BillPughSingleton();
    }

    public static BillPughSingleton getInstance() {
        return SingletonHelper.INSTANCE;
    }
}

Pros

  • Initialized only when needed.
  • Allows for exception handling.
  • Thread-Safe
  • Works well even in Java 5

Cons

  • Reflection can destroy this Singleton implementation.

Enum Singleton

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
package edu.redwoods.singleton;

public enum EnumSingleton {

    INSTANCE;

    public static void doSomething() {
        // do something
    }
}

Pros

  • Enum guarantees single instantiation and global access.
  • Thread-Safe
  • Reflection CANNOT destroy this Singleton implementation.

Cons

  • Created even if client doesn’t use it.

How Reflection Destroys Most Singleton Implementations!

 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
ipackage edu.redwoods.singleton;

import java.lang.reflect.Constructor;

public class ReflectionSingletonTest {

    public static void main(String[] args) {
        EagerInitializedSingleton instanceOne = EagerInitializedSingleton.getInstance();
        EagerInitializedSingleton instanceTwo = null;
        try {
            Constructor[] constructors = EagerInitializedSingleton.class.getDeclaredConstructors();
            for (Constructor constructor : constructors) {
                // This code will destroy the singleton pattern
                constructor.setAccessible(true);
                instanceTwo = (EagerInitializedSingleton) constructor.newInstance();
                break;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println(instanceOne.hashCode());
        System.out.println(instanceTwo.hashCode());
    }

}

Issues with Serialization

  • Serialization is when we need to store an object to the file-system, or other storage media, for later retrieval.
  • The de-serialization of the stored object creates a new instance, however. This defeats the idea of a Singleton.

Example of Defeating Singleton with De-serialization

 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
package edu.redwoods.singleton;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
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 SingletonSerializedTest {

    public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException {
        SerializedSingleton instanceOne = SerializedSingleton.getInstance();
        ObjectOutput out = new ObjectOutputStream(new FileOutputStream(
                "filename.ser"));
        out.writeObject(instanceOne);
        out.close();

        // de-serialize from file to object
        ObjectInput in = new ObjectInputStream(new FileInputStream(
                "filename.ser"));
        SerializedSingleton instanceTwo = (SerializedSingleton) in.readObject();
        in.close();

        System.out.println("instanceOne hashCode="+instanceOne.hashCode());
        System.out.println("instanceTwo hashCode="+instanceTwo.hashCode());

    }

}

How to fix Serialization Issue

  • Add an override of readResolve method to your Singleton
1
2
3
protected Object readResolve() {
    return getInstance();
}