我了解同步和volatile的功能以及在何处使用它们。我刚刚学习了volatile,而对于什么时候可以使用无波动的同步感到困惑。如果我同步一个对象,则需要阻止其他线程使用同一对象,但是在大多数情况下,我会这样做来编辑该对象,如果是这样,则需要对正在编辑的属性进行修改。
以下代码是关于比赛条件的,我想知道为什么我从未见过有人在count变量上使用volatile:
public synchronized void add(int value){
this.count += value;
}
这里不应该算是波动的吗?
我只是想弄清楚可以在没有volatile的情况下使用同步的情况,一段代码会有所帮助。
答案 0 :(得分:1)
很明显volatile
不足以实现计数器,因为它不能保证原子性。但是,如果读取的内容大大超过修改的内容,则可以结合使用内在锁定和易失性变量来减少公共代码路径上的开销。检查一下,
public class Counter {
@GuardedBy("this") private volatile int value;
public int getValue() { return value; }
public synchronized int increment() {
return value++;
}
}
该代码使用同步来确保增量操作是原子的,并使用易失性来保证当前结果的可见性。如果不经常更新,则此方法可能会更好,因为读取路径上的开销仅为volatile
读取,通常比锁获取便宜。