@lightstorm

Корректен ли double-checked locking через AtomicReference в Java?

Есть класс-кеш с отложенной инициализацией такого вида:
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
    }
}

Ключевой момент здесь, строка:
object = new AtomicReference(createObject()).get();

Т.е. создается объект, присваивается volatile переменной (по сути AtomicReference), после чего присваивается не защищенной переменной object. Предполагаем, что возвращаемый объект неизменяем.
Корректен ли такой подход?
Все возможные варианты double-check-а из википедии просьба не предлагать. Интересует лишь корректность данного кода и чем причина ошибки, если он все-же не безопасен.
  • Вопрос задан
  • 427 просмотров
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы