Performant и потокобезопасный блок инициализации - PullRequest
0 голосов
/ 04 мая 2018

Я просто наткнулся на следующий фрагмент кода, и мне интересно, есть ли более красивая альтернатива, которая имеет такую ​​же производительность.

if (!isInitialized) {
    synchronized (this) {
        if (!isInitialized) {
            // Initialization code
            isInitialized = true;
        }
    }           
}

Конечно, внешний оператор if может быть удален без ущерба для безопасности потока. Но это может повлиять на производительность, когда несколько потоков будут вызывать код одновременно, поскольку проверка isInitialized может выполняться только в одном потоке одновременно.

Выполнение инициализации в статическом контексте невозможно.

1 Ответ

0 голосов
/ 04 мая 2018

Эта идиома двойной проверки (DCI или DCL для двойной проверки блокировки) известна своим недостатком из-за переупорядочения команд.

Это работает, только если вы объявите переменную isInitialized как volatile, и только с jdk1.5 + (когда семантика volatile и модель памяти исправлены).

Честно говоря, это уже не так часто, с таким большим количеством плохой прессы ... LOL.

...