类 | 描述 |
---|---|
AtomicBoolean |
一个
boolean 值可以用原子更新。
|
AtomicInteger |
可能原子更新的
int 值。
|
AtomicIntegerArray |
一个
int 数组,其中元素可以原子更新。
|
AtomicIntegerFieldUpdater<T> |
基于反射的实用程序,可以对指定类的指定的
volatile int 字段进行原子更新。
|
AtomicLong |
一个
long 值可以用原子更新。
|
AtomicLongArray |
可以
long 地更新元素的
long 数组。
|
AtomicLongFieldUpdater<T> |
基于反射的实用程序,可以对指定类的指定的
volatile long 字段进行原子更新。
|
AtomicMarkableReference<V> |
AtomicMarkableReference 维护一个对象引用以及可以原子更新的标记位。
|
AtomicReference<V> |
可以原子更新的对象引用。
|
AtomicReferenceArray<E> |
可以以原子方式更新元素的对象引用数组。
|
AtomicReferenceFieldUpdater<T,V> |
一种基于反射的实用程序,可以对指定类的指定的
volatile volatile引用原子更新。
|
AtomicStampedReference<V> |
AtomicStampedReference 维护对象引用以及可以原子更新的整数“印记”。
|
DoubleAccumulator |
一个或多个变量一起维护使用提供的功能更新的运行的值
double 。
|
DoubleAdder |
一个或多个变量一起保持初始为零
double 和。
|
LongAccumulator |
一个或多个变量,它们一起保持运行
long 使用所提供的功能更新值。
|
LongAdder |
一个或多个变量一起保持初始为零
long 总和。
|
volatile
值,字段和数组元素的那些也提供以下形式的原子条件更新操作:
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)
写你的实用方法如下:
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 }
访问和更新原子的记忆效应通常遵循挥发物的规则,如The Java Language Specification (17.4 Memory Model)所述 :
get
具有读取volatile
变量的记忆效应。 set
具有写(分配) volatile
变量的记忆效应。 lazySet
具有写入(分配) volatile
变量的记忆效应,除了它允许重新排序与后续(但不是先前)存储器动作,它们本身不会对普通非volatile
写入施加重新排序volatile
。 在其他使用上下文中, lazySet
可以在为了垃圾收集而被归零时应用于再次不会被访问的引用。 weakCompareAndSet
原子方式读取和有条件地写入一个变量,但不会产生任何事先的排序,因此对于weakCompareAndSet以外的任何变量的前一次或后续读取和写入都不提供任何weakCompareAndSet
。 compareAndSet
和所有其他读取和更新操作(如getAndIncrement
具有读写volatile
变量的记忆效应。 除了表示单个值的类之外,此程序包还包含Updater类,可用于在任何所选volatile
任何选定的volatile
字段上获取compareAndSet
操作。 AtomicReferenceFieldUpdater
, AtomicIntegerFieldUpdater
和AtomicLongFieldUpdater
是基于反射的实用程序,提供对相关联的字段类型。 这些主要用于原子数据结构中,其中相同节点(例如,树节点的链接)的多个volatile
字段独立地受到原子更新的影响。 这些类可以在如何和何时使用原子更新方面提供更大的灵活性,牺牲更加尴尬的基于反射的设置,不太方便的使用和更弱的保证。
的AtomicIntegerArray
, AtomicLongArray
和AtomicReferenceArray
类进一步扩展到这些类型的数组原子操作的支持。 这些类别对于为其数组元素提供volatile
访问语义也是值得注意的,这对普通数组是不支持的。
原子类也支持方法weakCompareAndSet
,其适用性有限。 在某些平台上,所述弱版本可以比更有效compareAndSet
在正常情况下,但不同之处在于的任何给定调用weakCompareAndSet
方法可返回false
不合逻辑地 (即,没有明显的原因)。 一个false
返回只意味着如果需要,可以重试该操作,依赖于当该变量保持expectedValue
时重复调用的expectedValue
,并且没有其他线程也尝试设置该变量将最终成功。 (这样的虚假故障可能是由于与预期值和当前值是否相等无关的内存争用效应)。另外, weakCompareAndSet
不提供同步控制通常需要的排序保证。 然而,当这样的更新与程序的排序之前的另一个发生无关时,该方法可用于更新计数器和统计信息。 当线程看到由weakCompareAndSet
引起的原子变量的更新时,它不一定会看到在weakCompareAndSet
之前发生的任何其他变量的weakCompareAndSet
。 例如,如果更新性能统计数据,但很少有其他的情况,这可能是可以接受的。
AtomicMarkableReference
类将一个布尔值与引用相关联。 例如,该位可能在数据结构中使用,意味着被引用的对象在逻辑上被删除。 AtomicStampedReference
类将整数值与引用相关联。 这可以用于例如表示对应于一系列更新的版本号。
原子类主要设计为实现非阻塞数据结构和相关基础设施类的构建块。 compareAndSet
方法不是锁定的一般compareAndSet
方法。 仅当对象的关键更新仅限于单个变量时,才适用。
原子类不是通用替代java.lang.Integer
和相关类。 他们没有定义的方法,如equals
, hashCode
和compareTo
。 (因为原子变量预计会被突变,所以它们是散列表键的不好选择。)此外,类仅提供给预期应用程序通常有用的类型。 例如,对于表示无原子类byte
。 在那些您不希望这样做的情况下,您可以使用AtomicInteger
来保存byte
值,并适当地投射。 您也可以使用Float.floatToRawIntBits(float)
和Float.intBitsToFloat(int)
转换来持有浮点数,并使用Double.doubleToRawLongBits(double)
和Double.longBitsToDouble(long)
转换双倍。