Думаю, насправді ніхто не відповів на запитання , тому спробую.
Нестійкі та перші if (instance == null)
не є "необхідними". Блокування зробить цей код потокобезпечним.
Тож питання: чому б ви додали перше if (instance == null)
?
Причиною є, мабуть, уникнення непотрібного виконання заблокованого розділу коду. Поки ви виконуєте код всередині блокування, будь-який інший потік, який намагається також виконати цей код, блокується, що уповільнить вашу програму, якщо ви намагатиметеся часто отримувати доступ до одиночного з багатьох потоків. Залежно від мови / платформи, також можуть бути накладні витрати від самого замку, яких ви хочете уникнути.
Отже, перша нульова перевірка додана як дуже швидкий спосіб дізнатись, чи потрібен вам замок. Якщо вам не потрібно створювати синглтон, ви можете повністю уникнути блокування.
Але ви не можете перевірити, чи є посилання нульовим, не заблокувавши його якимось чином, оскільки через кешування процесора інший потік може його змінити, і ви прочитаєте "застаріле" значення, яке призведе до того, що ви введете блокування без потреби. Але ви намагаєтесь уникнути замку!
Таким чином, ви робите синглтон летким, щоб переконатись, що ви зчитуєте останнє значення, без необхідності використовувати замок.
Вам все ще потрібен внутрішній замок, оскільки енергонезалежний захищає вас лише під час одноразового доступу до змінної - ви не можете перевірити та встановити її безпечно, не використовуючи блокування.
Тепер, чи насправді це корисно?
Ну, я б сказав "у більшості випадків ні".
Якщо Singleton.Instance може спричинити неефективність через замки, то чому ви дзвоните йому так часто, що це може бути значною проблемою ? Вся суть синглтона в тому, що існує лише один, тому ваш код може читати та кешувати посилання на синглтон один раз.
Єдиний випадок, коли я можу придумати, де це кешування неможливе, - це коли у вас велика кількість потоків (наприклад, сервер, який використовує новий потік для обробки кожного запиту, може створювати мільйони дуже короткочасних потоків, кожен з яких який повинен був би зателефонувати Сінглтону. Екземпляр один раз).
Тож я підозрюю, що подвійне перевірене блокування - це механізм, який має реальне місце у дуже конкретних випадках, що критично важливі для продуктивності, і тоді всі ламали голову про "це правильний спосіб зробити", насправді не думаючи, що це робить і чи є буде фактично необхідним у тому випадку, якщо вони його використовують.