A singleton class is something for which only one instance exists per class loader. Single instance for a wholeapplication cannot be guaranteed. That is just definition of what is singleton.
The one that is popular with the interviewers is writing a thread-safe singleton class.
For example, the following singleton class is not thread-safe because before a thread creates the Singleton instance, another thread can proceed to the instantiation part of the code
— instance = new Object( );
to create more than one instance of the Singleton object.
Even though the code
–> instance = new Object( );
appears to be single line, the JVM has to execute a number of internal steps like allocating memory, creating a new object and assigning the newly created object to the referenced variable.
Only after the completion of these steps,the condition instance == null will return false.
// final so that cannot be subclassed
public final class Singleton {
private static Object instance = null;
//private so that it cannot be instantiated from outside this class
private Singleton() {}
public static Object getInstance() {
if (instance == null) {
instance = new Object();
}
return instance;
}
}
So, we can make the above code thread-safe in a number of ways.
Option 1: Synchronize the whole method or the block of code. This approach is not efficient as the use of synchronized keyword in a singleton class means that only one thread will be executing the synchronized block at a time and all other threads would be waiting.
Option 2: Eagerly initialize the singleton instance when the class is actually loaded as opposed to initializing it lazily at at run time only when it is accessed.
//final so that cannot be subclassed
public final class ThreadSafeSingleton {
//eager initialization and instantitiated as soon as the class is loaded by a classloader in the JVM
private static Object instance = new Object();
//private so that it cannot be instantiated from outside this class
private Singleton() {}
public static Object getInstance() {
return instance;
}
}
Option 3: You can use the “Initialize-On-Demand Holder Class” idiom proposed by Brian Goetz to create a thread-safe lazy-initialized Singleton as shown below by creating an inner class.
public final class ThreadSafeSingleton {
// private so that it cannot be instantiated from outside this class
private ThreadSafeSingleton() {}
// static inner class, invoked only when ThreadSafeSingleton.getInstance() is called
private static class ThreadSafeSingletonHolder {
private static ThreadSafeSingleton instance = new ThreadSafeSingleton();
}
public static Object getInstance() {
return ThreadSafeSingletonHolder.instance;
}
}
Option 4: is to create a per thread singleton as discussed earlier with the ThreadLocal class for the SimpledateFormat.