说你有这个代码:
private String cachedToken;
private final Object lockObject = new Object();
....
retrieveToken(){
synchronized(lockObject){
if (cachedToken == null){
cachedToken = goGetNewToken();
}
return cachedToken;
}
}
请写信给 cachedToken
对于已锁定的所有线程都可见 lockObject
?
是。在lockObject上同步会在关系之前建立一个Happens(也就是设置一个内存屏障)。这意味着随后获得锁定的所有线程将看到先前保持锁定时发生的任何更改。
但是,对于它的价值,你的延迟初始化的实现是有缺陷的。这是正确的方法:
private volatile String cachedToken;
retrieveToken() {
if (cachedToken == null) {
synchronized(lockObject) {
if (cachedToken == null) {
cachedToken = goGetNewToken();
}
}
}
return cachedToken
}
这样,当Threads首次开始请求时,您只需要少量锁定。之后,cachedToken将不为null,您将不需要同步。
当然, synchronize
确保两件事:
- 原子性
- 整个对象的内存障碍(在您的情况下您所期望的)
例如, volatile
确保内存屏障,但不处理原子性。