Quantcast
Channel: double check locking without volatile (but with VarHandle release/acquire) - Stack Overflow
Viewing all articles
Browse latest Browse all 3

double check locking without volatile (but with VarHandle release/acquire)

$
0
0

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?


Viewing all articles
Browse latest Browse all 3

Latest Images

Trending Articles





Latest Images

<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>
<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596344.js" async> </script>