"标准"写的副本代码如下:
...
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修饰符。我错了吗?
答案 0 :(得分:2)
据我所知,对象引用赋值操作是原子
是的,但是volatile
modifier不是关于原子赋值,而是关于读取此变量的所有线程,此变量的值都是相同的。
它实际上是关于原子变量访问,而不是关于原子变量赋值。
答案 1 :(得分:1)
来自"Atomic Access" in the Java Tutorials(强调我的):
原子操作不能交错,因此可以使用它们而不用担心线程干扰。但是,这并不能消除所有同步原子操作的需要,因为仍然可能存在内存一致性错误。使用volatile变量可以降低内存一致性错误的风险,因为对volatile变量的任何写入都会建立与之后读取同一变量的先发生关系。这意味着对volatile变量的更改始终对其他线程可见。