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