Блокировка с двойной проверкой безопасна на Java, при условии, что:
- переменная экземпляра объявлена как
volatile
, И
- JVM правильно реализует спецификацию JSR-133; то есть он совместим с Java 5 и более поздними версиями.
Мой источник - часто задаваемые вопросы JSR-133 (Модель памяти Java) - Джереми Мэнсон и Брайан Гетц, февраль 2004 . Это подтверждается Гетцем в ряде других мест.
Однако, как говорит Гетц, это идиома, время которой прошло. Необусловленная синхронизация в Java теперь быстрая, поэтому он рекомендует просто объявить метод getInstance()
как synchronized
, если вам нужно выполнить отложенную инициализацию. (И я думаю, что это относится и к другим языкам ...)
Кроме того, при прочих равных условиях писать код, работающий на Java 5, но ненадежный в старых JVM, - плохая идея.
ОК, а как насчет других языков? Ну, это зависит от того, как идиома реализована, и часто на платформе.
C # - в соответствии с https://stackoverflow.com/a/1964832/139985, это зависит от платформы, требуется ли переменной экземпляра для волатильности. Однако Википедия говорит, что если вы используете volatile
или явные барьеры памяти, идиома может быть реализована безопасно.
VB - согласно Wikipedia идиома может быть безопасно реализована с использованием явных барьеров памяти.
C ++ - согласно Wikipedia идиома может быть безопасно реализована с использованием volatile
в Visual C ++ 2005. Но другие источники говорят, что в общем спецификация языка C ++ не не предоставить достаточных гарантий для volatile
, чтобы быть уверенным. Однако двойная проверка блокировки может быть реализована в контексте языковой ревизии C ++ 2011 - https://stackoverflow.com/a/6099828/139985.
(Примечание: я просто суммирую некоторые источники, которые я нашел, которые кажутся мне недавними ... и звучат. Я не эксперт по C ++, C # или VB. Пожалуйста, прочитайте связанные страницы и сделайте свое собственное суждение. )