1

I was reading about volatile when I came across this statement that using volatile and synchronize keyword would slow down your overall performance hence the following code to make a singleton class

public enum Singleton {
 INSTANCE 
} 

Is better making a singleton class which includes a volatile instance and a synchronised method to return that static instance.

Though both the classes are thread safe and give the same desired result. Apart from the code readability , are there are any performance benefits of using enums.

LuCio
  • 5,055
  • 2
  • 18
  • 34
teczarina
  • 72
  • 11
  • To only answer your question in the title: From what I remember from university, volatile skips the CPU's cache and stores the variable directly in the RAM. This is obviously slower, as discussed here: https://softwareengineering.stackexchange.com/questions/234253/why-is-cpu-cache-memory-so-fast/234258 – maio290 Sep 05 '18 at 14:23
  • Enums are not volatile. They only guarantee the singleton functionality which is why they are best used for singletons. – OldCurmudgeon Sep 05 '18 at 14:27

2 Answers2

3

Maybe volatile does not do what you think it does. The text of your question looks like you are asking about two different ways of safely publishing a singleton in a multi-threaded environment. But, that is not what volatile is for. volatile solves a more general problem.

You can declare a variable to be volatile if it needs to be shared between different threads, but it does not need to be synchronized with any other variable. The volatile declaration ensures that any time a thread looks at the variable, it always will see the newest value that was assigned to it, even if that value was assigned by some other thread.

Yes. volatile is costly. It would be a mistake to use it when you don't need it (e.g., it would be a mistake to use it on a variable that is not shared, and it would be a mistake to use it on a shared variable that already is protected by other means.)

Ohm's Lawman
  • 293
  • 1
  • 6
1

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