假设你有这段代码:
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/