双重检查锁定是否仅在延迟初始化场景中被破坏?

时间:2015-01-24 12:35:22

标签: java multithreading double-checked-locking

我读过这篇文章:The "Double-Checked Locking is Broken" Declaration,它说

  

Double-Checked Locking被广泛引用并用作有效的方法   用于在多线程环境中实现延迟初始化。

     

不幸的是,它无法以独立于平台的方式可靠地工作   在Java中实现时......

这篇文章:Double-checked locking: Clever, but broken,它说:

  

DCL习惯用于支持延迟初始化......

我的问题是:

  1. 在尝试进行延迟初始化时,双重检查锁定是否仅被破坏?

  2. 它是否也像下面的代码一样被破坏了(所有东西都已经初始化了)?

  3. 代码:

    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 个答案:

答案 0 :(得分:1)

回答你的1:是的。从Java 5类加载器保证静态字段的单次或一次初始化。 回答你的2:从代码中不清楚,但这取决于你在wxMpConfigStorage.isJsapiTicketExpired()方法中读到的内容。如果您基于读取非线程安全的东西来决定那么是DCL可能会失败。但在你的情况下,jsapiTicketExpiresTime是易失性的,所以线程安全,因此DCL将适合你。