在这样的例子中:
...
public void foo() {
...
synchronized (lock) {
varA += some_value;
}
...
}
...
问题是,varA必须声明 volatile 以防止每个线程缓存,或者仅在 synchronized 块中访问它吗?
谢谢!
答案 0 :(得分:4)
不,你不需要。
synchronized
阻止意味着内存障碍。
来自JSR-133:
但是,除了相互排斥之外,还有更多的同步。同步确保线程在同步块之前或期间的内存写入以可预测的方式显示给在同一监视器上同步的其他线程。在我们退出synchronized块之后,我们释放了监视器,它具有将缓存刷新到主内存的效果,因此该线程所做的写操作对其他线程是可见的。在我们进入同步块之前,我们获取监视器,它具有使本地处理器高速缓存无效的效果,以便从主存储器重新加载变量。然后,我们将能够看到前一版本中显示的所有写入。
答案 1 :(得分:0)
只要每次访问它都来自同步块,那么你就可以了。
每个同步块都有一个内存屏障,可以确保正确访问内部访问的变量。