Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

singleton with volatile in java

class MyClass
{
      private static volatile Resource resource;

      public static Resource getInstance()
      {
            if(resource == null)
                  resource = new Resource();
            return resource;
      }
 }

Here my doubt is according to java concurrency in practice if you use volatile, safe publication happens (i.e. as soon the reference is visible to another thread the data is also available). So can I use it here? But if it is correct then suppose thread1 now checks "resource" and it's null so it starts creating the object. While thread1 is creating the objet another thread i.e. thread2 comes and start checking the value of "resource" and thread2 finds it as null (assume creating "resource" object takes some considerable amount of time and as thread1 has not yet completed the creation so the safe publication hasn't happened hence unavailable to thread2 )then will it also start creating the object? if yes then class invariant breaks. Am I correct? Please help me in understanding this specially use of volatile here.

like image 799
Trying Avatar asked Feb 25 '13 22:02

Trying


People also ask

Is volatile required in Singleton?

You need volatile on the member fields of the singleton itself (apply visibility feature).

What is the use of volatile in Singleton?

The volatile prevents memory writes from being re-ordered, making it impossible for other threads to read uninitialized fields of your singleton through the singleton's pointer.

How do you make a singleton class thread safe volatile?

Thread Safe Singleton in JavaCreate the private constructor to avoid any new object creation with new operator. Declare a private static instance of the same class. Provide a public static method that will return the singleton class instance variable.

What is volatile in Java?

Volatile keyword is used to modify the value of a variable by different threads. It is also used to make classes thread safe. It means that multiple threads can use a method and instance of the classes at the same time without any problem. The volatile keyword can be used either with primitive type or objects.

How to create a singleton class in Java?

In general, we follow the below steps to create a singleton class: Create the private constructor to avoid any new object creation with new operator. Declare a private static instance of the same class. Provide a public static method that will return the singleton class instance variable.

When to use volatile in singletons?

volatile on the singletons INSTANCE field is recommended whenever the singleton contains mutable state and is created using the double-checked locking idiom. So, in our example above, the answer is: although thread coordination worked fine without volatile, it should be applied.

Is Java singleton design pattern difficult to implement?

From the definition, it seems to be a very simple design pattern but when it comes to implementation, it creates a lot of implementation concerns. Also, the implementation of Java Singleton pattern has always been a controversial topic among developers.

What is the behavior of singleton instance in Java 8?

Following code demonstrates the behavior of Singleton instance, when two threads are getting executed by comparing their hash code values. Be careful while running the following code as it will work only in Java 8 and later versions. Moreover, we have used Method Reference in the code.


1 Answers

You are correct, multiple threads could try to create a Resource object. Volatile just guarantees that if one thread updates the reference, all other threads will see the new reference, not some cached reference. This is slower, but safer.

If you require only a single resource that is lazy loaded, you need to do something like this:

class MyClass
{
      private static volatile Resource resource;
      private static final Object LOCK = new Object();

      public static Resource getInstance()
      {
            if(resource == null) { 
                synchronized(LOCK) { // Add a synch block
                    if(resource == null) { // verify some other synch block didn't
                                           // write a resource yet...
                        resource = new Resource();
                    }
                }
            }
            return resource;
      }
 }
like image 113
corsiKa Avatar answered Sep 19 '22 17:09

corsiKa