简体   繁体   English

在Java synchronized块中,是在所有字段上显示还是只在同步变量上写入?

[英]In a Java synchronized block, are writes visible on all fields or just the synchronized variable?

Say you have this code: 说你有这个代码:

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

....


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

Will the write to cachedToken be visible to all threads that have locked on lockObject ? 将写入cachedToken是可见的已锁定的所有线程lockObject

Yes. 是。 Synchronizing on lockObject establishes a Happens Before Relationship (aka sets up a memory barrier). 在lockObject上进行同步会在关系之前建立一个Happens(也就是设置一个内存屏障)。 This means that all threads that subsequently get the lock will see any changes that happened while the lock was held previously. 这意味着随后获得锁定的所有线程将看到先前保持锁定时发生的任何更改。

For what it's worth, though, your implementation of lazy initialization is flawed. 但是,对于它的价值,你的延迟初始化的实现是有缺陷的。 This is the proper way: 这是正确的方法:

private volatile String cachedToken;

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

This way you only have to get the lock a small handful of times when Threads first start requesting it. 这样,当线程首次开始请求时,您只需要少量锁定。 After that the cachedToken will not be null, and you won't need to synchronize. 之后,cachedToken将不为null,您不需要同步。

Of course, synchronize ensure two things: 当然, synchronize确保两件事:

  • Atomicity 原子性
  • Memory barrier (what you expect in your case) on the entire object 整个对象的内存障碍(在您的情况下您所期望的)

Whereas for instance, volatile ensure memory barrier but doesn't handle atomicity. 然而,例如, volatile确保内存屏障但不处理原子性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM