synchronized
keyword by definition slow down the performance as it allows only one thread to process the synchronized code block. The only reason to use synchronized
and volatile
for creating a singleton class is to provide for lazy initialization of the single instance of the class.
private static volatile ThreadSafeLazySingleton instance;
private ThreadSafeLazySingleton(){}
public static synchronized ThreadSafeLazySingleton getInstance(){
if(instance == null){
instance = new ThreadSafeLazySingleton();
}
return instance;
}
Lazy initialization is helpful when the instantiation is resource heavy and you want to delay the creation of instance to the last moment.
It is possible to break the singleton design of a class by using Reflection
and setting the private constructor Singleton.class.getDeclaredConstructors()
access to true
by using constructor.setAccessible(true)
.
Using enum
to design a singleton class overcomes the above drawback as Java ensures that enums are always instantiated only once. However, the benefits of lazy initialization are lost in this approach. As synchronization is not used, this approach will have better performance than the synchronized approach.
The best way to design a singleton class is by using the method suggested in this answer