java - 在 Java 同步块(synchronized block)中,写入是在所有字段上可见还是仅在同步变量上可见?

标签 java concurrency synchronization

假设你有这段代码:

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

....


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

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

最佳答案

是的。在 lockObject 上同步建立了一个 Happens Before Relationship(又名设置了一个内存屏障)。这意味着所有随后获得锁的线程都将看到之前持有锁时发生的任何更改。

尽管如此,您对延迟初始化的实现是有缺陷的。这是正确的方法:

private volatile String cachedToken;

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

这样,当线程第一次开始请求时,您只需少数几次获得锁。之后cachedToken不为null,就不需要同步了。

关于java - 在 Java 同步块(synchronized block)中,写入是在所有字段上可见还是仅在同步变量上可见?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16653230/

相关文章:

java - JBoss 7 中的多线程问题

multithreading - 这是Go中的惯用工作线程池吗?

synchronization - SymmetricDS 同步未完美同步

java - 线程不同步

java - 如何从 Eclipse 将 Maven 项目的 WAR 部署到 JBoss 服务器?

Java - 动态网格布局

java - Android RelativeLayout 改变颜色 onClick

c# - 控制任务的实际并发性

c# - 当知道 xUnit 并行运行时,使用什么策略进行集成测试?

java - 双重检查锁定文章