我读过这篇文章:The "Double-Checked Locking is Broken" Declaration,它说
Double-Checked Locking被广泛引用并用作有效的方法 用于在多线程环境中实现延迟初始化。
不幸的是,它无法以独立于平台的方式可靠地工作 在Java中实现时......
这篇文章:Double-checked locking: Clever, but broken,它说:
DCL习惯用于支持延迟初始化......
我的问题是:
在尝试进行延迟初始化时,双重检查锁定是否仅被破坏?
它是否也像下面的代码一样被破坏了(所有东西都已经初始化了)?
代码:
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;
}
}
答案 0 :(得分:1)
回答你的1:是的。从Java 5类加载器保证静态字段的单次或一次初始化。 回答你的2:从代码中不清楚,但这取决于你在wxMpConfigStorage.isJsapiTicketExpired()方法中读到的内容。如果您基于读取非线程安全的东西来决定那么是DCL可能会失败。但在你的情况下,jsapiTicketExpiresTime是易失性的,所以线程安全,因此DCL将适合你。