volatile
values, fields, and array elements to those that also provide an atomic conditional update operation of the form:
boolean compareAndSet(expectedValue, updateValue);
这种方法(在不同类别的参数类型中有所不同)自动将变量设置为updateValue
如果它当前拥有expectedValue
,则报告true
成功。 此包中的类还包含获取并无条件设置值的方法,以及下面描述的较弱条件原子更新操作weakCompareAndSet
。
这些方法的规范使得实现能够采用在当代处理器上可用的高效的机器级原子指令。 但是在某些平台上,支持可能需要某种形式的内部锁定。 因此,这些方法并非严格保证是非阻塞的 - 在执行操作之前,线程可能会暂时阻塞。
类的实例AtomicBoolean
, AtomicInteger
, AtomicLong
和AtomicReference
各自提供访问和更新相应的类型的单个变量。 每个类还为该类型提供适当的实用方法。 例如,类AtomicLong
和AtomicInteger
提供原子增量方法。 一个应用程序是生成序列号,如下所示:
class Sequencer {
private final AtomicLong sequenceNumber
= new AtomicLong(0);
public long next() {
return sequenceNumber.getAndIncrement();
}
}
定义像getAndIncrement
这样的新实用函数可以getAndIncrement
将一个函数自动应用于一个值。 例如,给一些转变
long transform(long input)
write your utility method as follows:
long getAndTransform(AtomicLong var) {
long prev, next;
do {
prev = var.get();
next = transform(prev);
} while (!var.compareAndSet(prev, next));
return prev; // return next; for transformAndGet
}
对于访问和更新原子的记忆效应通常遵循挥发物的规则,如 Chapter 17 of The Java™ Language Specification中所述 :
get
has the memory effects of reading a volatile
variable. set
has the memory effects of writing (assigning) a volatile
variable. lazySet
has the memory effects of writing (assigning) a volatile
variable except that it permits reorderings with subsequent (but not previous) memory actions that do not themselves impose reordering constraints with ordinary non-volatile
writes. Among other usage contexts, lazySet
may apply when nulling out, for the sake of garbage collection, a reference that is never accessed again. weakCompareAndSet
atomically reads and conditionally writes a variable but does not create any happens-before orderings, so provides no guarantees with respect to previous or subsequent reads and writes of any variables other than the target of the weakCompareAndSet
. compareAndSet
and all other read-and-update operations such as getAndIncrement
have the memory effects of both reading and writing volatile
variables. 除了表示单个值的类外,此软件包还包含更新程序类,可用于在任何选定类的任何选定volatile
字段上获取compareAndSet
操作。 AtomicReferenceFieldUpdater
, AtomicIntegerFieldUpdater
,和AtomicLongFieldUpdater
是基于反射的实用程序,提供对相关联的字段类型。 这些主要用于原子数据结构,其中同一节点的多个volatile
字段(例如,树节点的链接)独立进行原子更新。 这些类在更多的方式和时间使用原子更新方面提供了更大的灵活性,其代价是更加尴尬的基于反射的设置,不太方便的使用以及较弱的保证。
的AtomicIntegerArray
, AtomicLongArray
和AtomicReferenceArray
类进一步扩展到这些类型的数组原子操作的支持。 这些类还为数组元素提供volatile
访问语义,值得注意,普通数组不支持这些语义。
原子类还支持方法weakCompareAndSet
,该方法的weakCompareAndSet
有限。 在某些平台上,弱版本在正常情况下可能比compareAndSet
更有效,但不同之处在于,任何给定的weakCompareAndSet
方法调用可能会虚假地返回false
(即,没有明显原因)。 如果需要, false
返回意味着操作可能会被重试,这取决于保证变量保持expectedValue
时的重复调用,并且没有其他线程也尝试设置该变量将最终成功。 (例如,这种虚假故障可能是由于与期望值和当前值是否相等无关的存储器争用效应造成的。)另外, weakCompareAndSet
不提供同步控制通常需要的排序保证。 但是,该方法可能对更新计数器和统计数据时非常有用,这些更新与其他更新无关 - 在程序的排序之前。 当线程看到由weakCompareAndSet
引起的对原子变量的更新时,它不一定会看到对weakCompareAndSet
之前发生的任何其他变量的weakCompareAndSet
。 例如,当更新性能统计数据时,这很可能是可以接受的,但很少有其他情况。
AtomicMarkableReference
类将一个布尔值与一个引用相关联。 例如,该位可能在数据结构中用于表示被引用的对象在逻辑上已被删除。 AtomicStampedReference
类将整数值与引用关联。 这可以用于例如表示与一系列更新对应的版本号。
原子类主要被设计为用于实现非阻塞数据结构和相关基础结构类的构建块。 compareAndSet
方法不是锁定的一般替代方法。 它仅适用于对象的关键更新仅限于单个变量的情况。
原子类不是java.lang.Integer
和相关类的通用替代品。 他们没有定义方法,比如equals
, hashCode
和compareTo
。 (因为原子变量预计会发生变化,所以它们是散列表键的糟糕选择。)此外,仅为那些在预期应用程序中通常有用的类型提供类。 例如,没有代表byte
原子类。 在那些你希望这样做的AtomicInteger
情况下,你可以使用AtomicInteger
来保存byte
值,并进行适当的转换。 您还可以使用floatToRawIntBits(float)
和intBitsToFloat(int)
转换来持有浮动,并使用doubleToRawLongBits(double)
和longBitsToDouble(long)
转换将持有浮动。
AtomicBoolean | 可能以原子方式更新的 boolean 值。 |
AtomicInteger | 可能以原子方式更新的 int 值。 |
AtomicIntegerArray | 可以自动更新元素的 int 数组。 |
AtomicIntegerFieldUpdater<T> | 基于反射的实用程序,可以将原子更新指定为指定类的指定 volatile int 字段。 |
AtomicLong | 可以自动更新的 long 值。 |
AtomicLongArray | 可以自动更新元素的 long 数组。 |
AtomicLongFieldUpdater<T> | 基于反射的实用程序,可以将原子更新指定到指定类的指定 volatile long 字段。 |
AtomicMarkableReference<V> | 一个 AtomicMarkableReference 维护一个对象引用以及一个标记位,可以自动更新。 |
AtomicReference<V> | 可以自动更新的对象引用。 |
AtomicReferenceArray<E> | 元素可以以原子方式更新的对象引用数组。 |
AtomicReferenceFieldUpdater<T, V> | 基于反射的实用程序,可以将原子更新指定为指定类的指定 volatile 参考字段。 |
AtomicStampedReference<V> | 一个 AtomicStampedReference 维护一个对象引用以及一个整数“stamp”,可以自动更新。 |
DoubleAccumulator | 一个或多个变量,它们一起保持运行 double 使用所提供的功能更新值。 |
DoubleAdder | 一个或多个变量,它们共同维持最初的零 double 总和。 |
LongAccumulator | 一个或多个变量,它们一起保持运行 long 使用所提供的功能更新值。 |
LongAdder | 一个或多个变量,它们共同维持最初的零 long 总和。 |