【问题标题】:Do variables accessed within synchronised block must be declared volatile?在同步块中访问的变量是否必须声明为 volatile?
【发布时间】:2014-07-30 00:14:44
【问题描述】:
在这样的例子中:
...
public void foo() {
...
synchronized (lock) {
varA += some_value;
}
...
}
...
问题是,是否必须将 varA 声明为 volatile 以防止每个线程缓存,或者仅在 同步 块内访问它就足够了?
谢谢!
【问题讨论】:
标签:
java
synchronization
synchronized
volatile
【解决方案1】:
不,您不需要。
synchronized 块意味着内存屏障。
来自JSR-133:
但同步不仅仅是互斥。同步确保线程在同步块之前或期间写入的内存以可预测的方式对在同一监视器上同步的其他线程可见。退出同步块后,我们释放监视器,这具有将缓存刷新到主内存的效果,以便该线程进行的写入可以对其他线程可见。在我们进入同步块之前,我们获取了监视器,它具有使本地处理器缓存无效的效果,以便从主内存重新加载变量。然后,我们将能够看到以前版本中可见的所有写入。
【解决方案2】:
只要对它的每次访问都来自同步块内,那么你就可以了。
每个同步块都有一个内存屏障,可确保在其中访问的变量正确公开。