在CopyOnWrite

时间:2016-07-17 12:24:41

标签: java concurrency copy-on-write

"标准"写的副本代码如下:

...
private volatile SomeClass object;

private ReentrantLock lock = new ReentrantLock();

public change (...) {
    lock.lock(); //set lock on write
    try {
        SomeClass newObject  = new SomeClass();
        //do something with new object
        ...
        //set new object
        object = newObject;
    } finally {
        lock.unlock(); //release lock
    }
}

public Object getSomeField () {
    SomeClass obj = object;
    return obj.getSomeField();
}

问题:为什么保持参考的字段在写入时保护"宾语 是不稳定的? (例如,参见CopyOnWriteArrayList的实现)。 据我所知,对象引用赋值操作是原子的, 所以看起来没有必要使用volatile修饰符。我错了吗?

2 个答案:

答案 0 :(得分:2)

  

据我所知,对象引用赋值操作是原子

是的,但是volatile modifier不是关于原子赋值,而是关于读取此变量的所有线程,此变量的值都是相同的。

它实际上是关于原子变量访问,而不是关于原子变量赋值。

答案 1 :(得分:1)

来自"Atomic Access" in the Java Tutorials(强调我的):

  

原子操作不能交错,因此可以使用它们而不用担心线程干扰。但是,这并不能消除所有同步原子操作的需要,因为仍然可能存在内存一致性错误。使用volatile变量可以降低内存一致性错误的风险,因为对volatile变量的任何写入都会建立与之后读取同一变量的先发生关系。这意味着对volatile变量的更改始终对其他线程可见