假设您有以下代码:

private String cachedToken;
private final Object lockObject = new Object();

....


retrieveToken(){
 synchronized(lockObject){
  if (cachedToken == null){
   cachedToken = goGetNewToken();
  }
  return cachedToken;
 }
}

cachedToken的写入是否对所有已锁定lockObject的线程可见?

最佳答案

是的。在lockObject上进行同步会建立“关系发生前”(aka设置内存屏障)。这意味着随后获得锁的所有线程将看到先前持有锁时发生的任何更改。

但是,就其值(value)而言,延迟初始化的实现存在缺陷。这是正确的方法:

private volatile String cachedToken;

retrieveToken() {
    if (cachedToken == null) {
        synchronized(lockObject) {
            if (cachedToken == null) {
                cachedToken = goGetNewToken();
            }
        }
    }
    return cachedToken
}

这样,当线程首次开始请求锁时,您只需要将锁锁定一小段时间。之后,cachedToken将不会为null,并且您将不需要进行同步。

10-08 01:12