2

What's the difference between a static and volatile reference from threading point of view? For example I want to have a singleton object and my code is like this:

class Singleton {
    Helper helper;   /*Shall I make this variable static or volatile*/

    Helper getHelper() {
          if(helper==null) {
              synchronized(this) {
                  if(helper==null) {  
                      helper=new Helper();
                  }
              }
          }
          return  helper;
     } 
}

Suppose there are two threads accessing the getHelper() method. To avoid multiple creation of Helper object and dirty read shall I make the reference static or volatile?

Can anyone please explain taking thread cache into picture?

Ordous
  • 3,844
  • 15
  • 25
Debapriya Biswas
  • 1,079
  • 11
  • 23

3 Answers3

4

For this sort of lazy initialization it needs to be volatile.

For it to be a singleton it needs to be static.

So you need both :)

There is a much neater pattern you can use for lazy initialization of a static singleton though which uses the class loader to do all the work for you:

class Singleton {
     private static class SingletonHolder {
          private static final Singleton instance;
     }

     Singleton getInstance() {
        return SingletonHolder.instance;
     }
}

The inner class is only loaded the first time you use it, which means it is lazily loaded from the point of view of the outer class. The class loader handles all of your synchronization for you though.

Tim B
  • 40,716
  • 16
  • 83
  • 128
1

From Head First Design Patterns if application is multitasking, you should use a private volatile static modificators. Volatile modifier ensures, that field is handled properly in multithread environment. Without it, there still might be a situation, where more than one object will by created. So your code should be like

class Singleton {
    private volatile static Helper helper;

    public static Helper getInstance(){
      if(helper==null) {
        synchronized(this) {
           if(helper==null){  
                 helper=new Helper();
           }
        }
    }
   return  helper;
   } 
}
T.G
  • 1,913
  • 1
  • 16
  • 29
  • It is important to note that this double checked locking (with volatile) will only work with java 1.5 or newer. While it is pretty unlikely to use anything older at this point, it is possible. – Brett Okken Jun 13 '14 at 11:41
  • You're right in both statements. double check mechanism don't work in JDK1.5 or older, and it is highly unlikely, that someone uses so old JDK versions (unless he work on very old system where everyone is to scared to try to transfer it to newer JDK) :) – T.G Jun 13 '14 at 11:58
0

If Helper is a heavy class and you only want to have a single one (inside your Singleton) you should make it static. The instantiation inside the synchronized block will stop it causing issues. However, any non-thread-safe methods inside your Helper class should also be appropriately synchronized.

Matt
  • 3,303
  • 5
  • 31
  • 53