Immutability and reordering

Приведенный ниже код (Java Concurrency in Practice, листинг 16.3) не является поточно-ориентированным по понятным причинам:

public class UnsafeLazyInitialization {
    private static Resource resource;

    public static Resource getInstance() {
        if (resource == null)
            resource = new Resource();  // unsafe publication
        return resource;
    }
}

Однако несколькими страницами позже, в разделе 16.3, они заявляют:

UnsafeLazyInitialization на самом деле безопасноесли Resource неизменен.

Я нене понимаю это утверждение:

ЕслиResource неизменен, любой поток, наблюдающийresource переменная будет иметь нулевое значение или полностью сконструирована (благодаря строгим гарантиям конечных полей, предоставляемых моделью памяти Java)Однако ничто не мешает переупорядочению команд: в частности, два чтенияresource может быть переупорядочен (есть одно чтение вif и один вreturn). Таким образом, поток мог видеть ненулевойresource вif условие, но возвращает нулевую ссылку (*).

Я думаюUnsafeLazyInitialization.getInstance() может вернуть ноль, даже еслиResource неизменен. Это так и почему (или почему нет)?

(*) Чтобы лучше понять мою мысль о переупорядочении,этот блог Джереми Мэнсон, один из авторов главы 17 JLS о параллелизме, объясняет, как String 's хеш-код безопасно публикуется через безопасную гонку данных, и как устранение использования локальной переменной может привести к тому, что хеш-код неверно вернет 0, из-за возможного переупорядочения, очень похожего на то, что я описал выше:

Что я'мы сделали, чтобы добавить дополнительное чтение: второе чтение хэша, перед возвратом. Как бы странно это ни звучало и как бы маловероятно ни было, первое чтение может вернуть правильно вычисленное значение хеш-функции, а второе чтение может вернуть 0! Это разрешено в рамках модели памяти, потому что модель допускает обширное переупорядочение операций. Второе чтение фактически может быть перемещено в вашем коде, так что ваш процессор сделает это раньше первого!

Ответы на вопрос(10)

Ваш ответ на вопрос