Является ли блокировка с двойной проверкой нарушенной только в сцене ленивой инициализации?
Я читаю эту статью: объявление "дважды проверенный замок сломан" , оно говорит
Блокировка с двойной проверкой широко цитируется и используется в качестве эффективного метода для реализации ленивой инициализации в многопоточной среде.
К сожалению, он не будет надежно работать независимо от платформы при реализации на Java...
И эта статья: дважды проверенный замок: умный, но сломанный , он говорит:
Инспектором фразеологизм был разработан для поддержки отложенной инициализации...
Мои вопросы:
-
Является ли блокировка с двойной проверкой нарушенной только при попытке выполнить ленивую инициализацию ?
-
Он также нарушается в сцене, подобной приведенному ниже коду (все вещи уже инициализированы)?
Код:
public String refreshJsapiTicket() throws WxErrorException {
if (wxMpConfigStorage.isJsapiTicketExpired()) {
synchronized (wxMpConfigStorage) {
if (wxMpConfigStorage.isJsapiTicketExpired()) {
// ...
// update
wxMpConfigStorage.setJsapiTicket(jsapiTicket, expiresInSeconds);
}
}
}
}
public class WxMpInMemoryConfigStorage implements WxMpConfigStorage {
protected volatile String jsapiTicket;
protected volatile long jsapiTicketExpiresTime;
public synchronized void updateJsapiTicket(String jsapiTicket, int expiresInSeconds) {
this.jsapiTicket = jsapiTicket;
this.jsapiTicketExpiresTime = System.currentTimeMillis() + (expiresInSeconds - 200) * 1000l;
}
}
1 ответ:
Ответ на ваш 1: Да. От Java 5 class loader гарантирует однократную или однократную инициализацию для статических полей. Ответ на ваш 2: из кода его не ясно, но это зависит от того, что Вы читаете в wxMpConfigStorage.метод isJsapiTicketExpired (). Если вы решаете, основываясь на чтении чего-то, что не является потокобезопасным, то да DCL может потерпеть неудачу. Но в вашем случае jsapiTicketExpiresTime является изменчивым и поэтому потокобезопасным для чтения, и поэтому DCL будет работать для вас.