Skip to main content

Singleton

Problem

  1. Ensure that a class has just a single instance

    The most common reason for this is to control access to some shared resource—for example, a database or a file.

    Here’s how it works: imagine that you created an object, but after a while decided to create a new one. Instead of receiving a fresh object, you’ll get the one you already created (not using constructor).

  2. Provide a global access point to that instance

    Maybe unsafe as any code can access the object and could potentially overwrite the content.

    Singleton protects the instance from being overwritten by other code.

Solution

  1. Make the default constructor private, to prevent other objects from using the new operator with the Singleton class.

  2. Create a static creation method that acts as a constructor. Under the hood, this method calls the private constructor to create an object and saves it in a static field. All following calls to this method return the cached object.

If your code has access to the Singleton class, then it’s able to call the Singleton’s static method. So whenever that method is called, the same object is always returned.

Sample Code

public final class Singleton {
private static Singleton instance;
public String value;

private Singleton(String value) {
// The following code emulates slow initialization.
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
this.value = value;
}

public static Singleton getInstance(String value) {
if (instance == null) {
instance = new Singleton(value);
}
return instance;
}
}
public class DemoSingleThread { 
public static void main(String[] args) {
System.out.println("If you see the same value, then singleton was reused (yay!)" + "\n" +
"If you see different values, then 2 singletons were created (booo!!)" + "\n\n" +
"RESULT:" + "\n");
Singleton singleton = Singleton.getInstance("FOO");
Singleton anotherSingleton = Singleton.getInstance("BAR");
System.out.println(singleton.value);
System.out.println(anotherSingleton.value);
}
}

Reference