The question is rather easy, in a way. Suppose I have this class:
static class Singleton {}
And I want to provide a singleton factory for it. I can do the (probably) obvious. I am not going to mention the enum possibility or any other, as they are of no interest to me.
static final class SingletonFactory { private static volatile Singleton singleton; public static Singleton getSingleton() { if (singleton == null) { // volatile read synchronized (SingletonFactory.class) { if (singleton == null) { // volatile read singleton = new Singleton(); // volatile write } } } return singleton; // volatile read }}
I can get away from one volatile read
with the price of higher code complexity:
public static Singleton improvedGetSingleton() { Singleton local = singleton; // volatile read if (local == null) { synchronized (SingletonFactory.class) { local = singleton; // volatile read if (local == null) { local = new Singleton(); singleton = local; // volatile write } } } return local; // NON volatile read}
This is pretty much what our code has been using for close to a decade now.
The question is can I make this even faster with release/acquire
semantics added in java-9
via VarHandle
:
static final class SingletonFactory { private static final SingletonFactory FACTORY = new SingletonFactory(); private Singleton singleton; private static final VarHandle VAR_HANDLE; static { try { VAR_HANDLE = MethodHandles.lookup().findVarHandle(SingletonFactory.class, "singleton", Singleton.class); } catch (Exception e) { throw new RuntimeException(e); } } private static Singleton getInnerSingleton() { Singleton localSingleton = (Singleton) VAR_HANDLE.getAcquire(FACTORY); // acquire if (localSingleton == null) { synchronized (SingletonFactory.class) { localSingleton = (Singleton) VAR_HANDLE.getAcquire(FACTORY); // acquire if (localSingleton == null) { localSingleton = new Singleton(); VAR_HANDLE.setRelease(FACTORY, localSingleton); // release } } } return localSingleton; }}
Would this be a valid and correct implementation?