L
L
lightstorm2015-08-17 23:52:03
Java
lightstorm, 2015-08-17 23:52:03

Is double-checked locking via AtomicReference correct in Java?

There is a cache class with lazy initialization of this kind:

final class SyncTest {
    private final Object NOT_INITIALIZED = new Object();
    private Object object;

    /**
     * It's guaranteed by outer code that creation of this object is thread safe
     * */
    public SyncTest() {
       object = NOT_INITIALIZED;
    }

    public Object getObject() {
        if (object == NOT_INITIALIZED) {
            synchronized (NOT_INITIALIZED) {
                if (object == NOT_INITIALIZED) {
                    object = new AtomicReference(createObject()).get();
                }
            }
        }
        return object;
    }

    /**
     * Creates some object which initialization is not thread safe
     * @return required object or NOT_INITIALIZED
     * */
    private Object createObject() {
        //do some work here
    }
}

Key point here, line:
object = new AtomicReference(createObject()).get();

Those. an object is created, assigned to a volatile variable (essentially an AtomicReference), and then assigned to an unprotected object variable. We assume that the returned object is immutable.
Is this approach correct?
Please do not offer all possible variants of double-check from Wikipedia. We are only interested in the correctness of this code and what is the cause of the error, if it is still not safe.

Answer the question

In order to leave comments, you need to log in

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question