Является ли блокировка с двойной проверкой нарушенной только в сцене ленивой инициализации?


Я читаю эту статью: объявление "дважды проверенный замок сломан" , оно говорит

Блокировка с двойной проверкой широко цитируется и используется в качестве эффективного метода для реализации ленивой инициализации в многопоточной среде.

К сожалению, он не будет надежно работать независимо от платформы при реализации на Java...

И эта статья: дважды проверенный замок: умный, но сломанный , он говорит:

Инспектором фразеологизм был разработан для поддержки отложенной инициализации...

Мои вопросы:

  1. Является ли блокировка с двойной проверкой нарушенной только при попытке выполнить ленивую инициализацию ?

  2. Он также нарушается в сцене, подобной приведенному ниже коду (все вещи уже инициализированы)?

Код:

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 3

1 ответ:

Ответ на ваш 1: Да. От Java 5 class loader гарантирует однократную или однократную инициализацию для статических полей. Ответ на ваш 2: из кода его не ясно, но это зависит от того, что Вы читаете в wxMpConfigStorage.метод isJsapiTicketExpired (). Если вы решаете, основываясь на чтении чего-то, что не является потокобезопасным, то да DCL может потерпеть неудачу. Но в вашем случае jsapiTicketExpiresTime является изменчивым и поэтому потокобезопасным для чтения, и поэтому DCL будет работать для вас.