软件包 java.util.concurrent.atomic 说明
支持对单个变量进行无锁线程安全编程的小型类工具包。本质上,这个包中的类将volatile值、字段和数组元素的概念扩展到那些还提供以下形式的原子条件更新操作的类:
boolean compareAndSet(expectedValue, updateValue);;
此方法(在不同类中的参数类型不同)自动将变量设置为updateValue如果它当前持有expectedValue,则报告true成功。此包中的类还包含获取和无条件设置值的方法,以及weakCompareAndSet下面描述的较弱的条件原子更新操作。
这些方法的规范使实现能够使用现代处理器上可用的高效机器级原子指令。但是在某些平台上,支持可能需要某种形式的内部锁定。因此,不能严格保证这些方法是非阻塞的——线程可能会在执行操作之前暂时阻塞。
类 AtomicBoolean、 AtomicInteger、 AtomicLong和 AtomicReference each 的实例提供对相应类型的单个变量的访问和更新。每个类还为该类型提供适当的实用方法。例如,类AtomicLong并 AtomicInteger提供原子增量方法。一种应用是生成序列号,如:
class Sequencer {
private final AtomicLong sequenceNumber
= new AtomicLong(0);
public long next() {
return sequenceNumber.getAndIncrement();
}
}
访问和更新原子的记忆效应通常遵循 volatiles 的规则,如 The Java™ Language Specification的第 17.4 节所述。
get具有读取 volatile变量的记忆效应。
set具有写入(分配) volatile变量的记忆效应。
lazySet具有写入(分配)volatile变量的记忆效应,除了它允许使用后续(但不是先前)内存操作进行重新排序,这些操作本身不会对普通非volatile 写入施加重新排序约束。在其他使用上下文中,lazySet可能适用于为了垃圾收集而清空一个永远不会再次访问的引用。
weakCompareAndSet原子地读取和有条件地写入一个变量,但不创建 任何发生前顺序,因此不提供关于先前或后续读取和写入的任何变量的保证,而不是weakCompareAndSet.
compareAndSet 以及所有其他读取和更新操作,例如getAndIncrement 具有读取和写入volatile变量的记忆效应。
除了表示单个值的类之外,此包还包含更新程序类,可用于获取 compareAndSet对任何选定类的任何选定volatile 字段的操作。 AtomicReferenceFieldUpdater、 AtomicIntegerFieldUpdater和 AtomicLongFieldUpdater是基于反射的实用程序,可提供对关联字段类型的访问。这些主要用于原子数据结构,其中volatile同一节点的多个字段(例如,树节点的链接)独立地进行原子更新。这些类在如何以及何时使用原子更新方面提供了更大的灵活性,但代价是基于反射的设置更笨拙、使用更不方便且保证更弱。
、 AtomicIntegerArray和 类进一步将原子操作支持扩展AtomicLongArray到 AtomicReferenceArray这些类型的数组。这些类在为其数组元素提供访问语义方面也很引人注目,volatile普通数组不支持这种语义。
原子类还支持weakCompareAndSet适用性有限的方法。在某些平台上,弱版本可能比compareAndSet正常情况下更有效,但不同之处在于任何给定的 weakCompareAndSet方法调用都可能false 虚假返回(即没有明显原因)。false返回仅意味着操作可以在需要时重试,依赖于当变量保持不变且没有其他线程也尝试设置变量时重复调用最终 expectedValue会成功的保证。(例如,此类虚假故障可能是由于与预期值和当前值是否相等无关的内存争用效应造成的。)此外weakCompareAndSet不提供同步控制通常需要的顺序保证。然而,当此类更新与程序的其他先行顺序无关时,该方法可能对更新计数器和统计信息很有用。当一个线程看到由 a 引起的对原子变量的更新时weakCompareAndSet,它不一定看到对发生在 之前的任何其他weakCompareAndSet变量的更新。例如,在更新性能统计信息时,这可能是可以接受的,但在其他情况下很少见。
该类AtomicMarkableReference 将单个布尔值与引用相关联。例如,该位可能在数据结构中使用,表示被引用的对象在逻辑上已被删除。该类AtomicStampedReference 将整数值与引用相关联。例如,这可以用来表示对应于一系列更新的版本号。
原子类主要设计为构建块,用于实现非阻塞数据结构和相关基础结构类。该compareAndSet方法不是锁定的一般替代方法。它仅适用于对象的关键更新仅限于单个变量的情况。
java.lang.Integer原子类不是和相关类的通用替代品 。它们不 定义诸如hashCode和 之类的方法compareTo。(因为预期原子变量会发生变化,所以它们不是哈希表键的糟糕选择。)此外,仅为那些在预期应用程序中通常有用的类型提供类。例如,没有用于表示的原子类byte。在您希望这样做的罕见情况下,您可以使用 an AtomicInteger来保存 byte值,并进行适当的转换。您还可以使用和转换保持浮动 Float.floatToIntBits(float), 并使用和 转换Float.intBitsToFloat(int)加倍 。Double.doubleToLongBits(double)Double.longBitsToDouble(long)
自从:
1.5