可以在不声明值 volatile 的情况下实现 java 原子整数吗?
can java atomic integer be implemented without declaring value volatile?
我突然想到 CAS
可以确保原子整数的原子性。那么为什么要费心声明底层 value
volatile
?
我知道volatile
防止编译器和硬件重新排序,并确保指令顺序。但这在这里相关吗?
这里有什么问题?没有 volatile
是什么问题?
所有声明为 volatile 的变量(包括 long 和 double 变量)的读写都是原子的。
...但是,这并不能消除所有需要同步的原子操作,因为内存一致性错误仍然是可能的。使用 volatile 变量可以降低内存一致性错误的风险,因为对 volatile 变量的任何写入都会与对该相同变量的后续读取建立先行关系。
假设它是 java.util.concurrent.atomic
包中的 Atomic*
类。
你在谈论两个不同的概念:对原子对象的引用和原子对象本身。
是的,同一个原子整数对象上的CAS
是原子的。但是我们如何确定两个线程中的 compareAndSet
方法调用应用于同一个对象呢?就像任何被多个线程共享的java对象一样,这与[atomic]对象的safe-publication有关。
这是 volatile
、final member variables
或锁定有用的地方。对对象的引用应由多个线程正确共享。
重新阅读问题后,我发现您可能会问为什么 AtomicInteger
中的 value
成员被声明为 volatile
。 对于初学者,不是所有的方法都是基于unsafe.compareAndSwapInt
,有简单的set
和get
直接访问value
字段,这足以说明这个字段是volatile
.我想知道 unsafe
操作也需要它。
我突然想到 CAS
可以确保原子整数的原子性。那么为什么要费心声明底层 value
volatile
?
我知道volatile
防止编译器和硬件重新排序,并确保指令顺序。但这在这里相关吗?
这里有什么问题?没有 volatile
是什么问题?
所有声明为 volatile 的变量(包括 long 和 double 变量)的读写都是原子的。
...但是,这并不能消除所有需要同步的原子操作,因为内存一致性错误仍然是可能的。使用 volatile 变量可以降低内存一致性错误的风险,因为对 volatile 变量的任何写入都会与对该相同变量的后续读取建立先行关系。
假设它是 java.util.concurrent.atomic
包中的 Atomic*
类。
你在谈论两个不同的概念:对原子对象的引用和原子对象本身。
是的,同一个原子整数对象上的CAS
是原子的。但是我们如何确定两个线程中的 compareAndSet
方法调用应用于同一个对象呢?就像任何被多个线程共享的java对象一样,这与[atomic]对象的safe-publication有关。
这是 volatile
、final member variables
或锁定有用的地方。对对象的引用应由多个线程正确共享。
重新阅读问题后,我发现您可能会问为什么 AtomicInteger
中的 value
成员被声明为 volatile
。 对于初学者,不是所有的方法都是基于unsafe.compareAndSwapInt
,有简单的set
和get
直接访问value
字段,这足以说明这个字段是volatile
.我想知道 unsafe
操作也需要它。