1.官方描述
1.1 单个变量AtomicBoolean, AtomicInteger, AtomicLong和AtomicReference
A small toolkit of classes that support lock-free thread-safe
programming on single variables. In essence, the classes in this
package extend the notion of volatile values, fields, and array
elements to those that also provide an atomic conditional update
operation of the form:
boolean compareAndSet(expectedValue, updateValue);
This method (which varies in argument types across different
classes) atomically sets a variable to the updateValue if it
currently holds the expectedValue, reporting true on success. The
classes in this package also contain methods to get and
unconditionally set values, as well as a weaker conditional atomic
update operation weakCompareAndSet described below.
The specifications of these methods enable implementations to
employ efficient machine-level atomic instructions that are
available on contemporary processors. However on some
platforms, support may entail some form of internal locking. Thus
the methods are not strictly guaranteed to be non-blocking -- a
thread may block transiently before performing the operation.
支持对单变量无锁线程安全编程。使用CAS拓展了volatile概念。
CAS一般采用高效机器级原子指令实现,但是在某些平台,可能需要内部锁来支持。因此,不严格保证方法是非阻塞的,线程可能在执行操作之前暂时阻塞。
Instances of classes AtomicBoolean, AtomicInteger, AtomicLong,
and AtomicReference each provide access and updates to a
single variable of the corresponding type. Each class also
provides appropriate utility methods for that type. For example,
classes AtomicLong and AtomicInteger provide atomic increment
methods. One application is to generate sequence numbers, as
in:
类AtomicBoolean, AtomicInteger, AtomicLong和AtomicReference的实例分别提供了对相应类型的单个变量的访问和更新,每个类还为该类型提供了适当的实用方法。例如,AtomicBoolean, AtomicInteger提供了原子增量方法。
class Sequencer {
private final AtomicLong sequenceNumber
= new AtomicLong(0);
public long next() {
return sequenceNumber.getAndIncrement();
}
}
It is straightforward to define new utility functions that, like
getAndIncrement, apply a function to a value atomically. For
example, given some transformation
long transform(long input)
定义新的实用程序函数很简单,像getAndIncrement,将函数原子地应用于值。
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
}
The memory effects for accesses and updates of atomics
generally follow the rules for volatiles, as stated in The Java
Language Specification (17.4 Memory Model):
* 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的规则,如果Java语言规范中所述(17.4 Memory Model):
- get等同于从volatile中读
- set等同于写volatile
- lazySet等同于写volatile,除了允许后续(不是前面的)内存操作重排序,这些内存操作不会对普通的non-volatile写施加重排序约束。在其他用法中,为了垃圾回收,lazySet可以在使一个不会再访问的引用置为null时使用。
- weakCompareAndSet原子读并有条件地写,但不会创建任何happens-before顺序,因此不会提供任何保证(与先前和后续的任何变量的读写)
- compareAndSet以及其他所有读取并更新的操作都具有读写volatile的内存效应。
1.2 域AtomicReferenceFieldUpdater, AtomicIntegerFieldUpdater及AtomicLongFieldUpdater
In addition to classes representing single values, this package
contains Updater classes that can be used to obtain
compareAndSet operations on any selected volatile field of any
selected class. AtomicReferenceFieldUpdater,
AtomicIntegerFieldUpdater, and AtomicLongFieldUpdater are
reflection-based utilities that provide access to the associated
field types. These are mainly of use in atomic data structures in
which several volatile fields of the same node (for example, the
links of a tree node) are independently subject to atomic updates.
These classes enable greater flexibility in how and when to use
atomic updates, at the expense of more awkward reflection-
based setup, less convenient usage, and weaker guarantees.
可以在任何类的volatile域上执行CAS操作。AtomicReferenceFieldUpdater, AtomicIntegerFieldUpdater及AtomicLongFieldUpdater这三个类是基于反射的,可提供对相关字段的访问。通常用于原子数据结构,在同一结点中有几个volatile域,可以独立地进行原子更新。这些类在如何以及何时使用原子更新方面提供了更大的灵活性,代价是笨拙的基于反射的设置,不太方便的使用和较弱的保证。
1.3 数组AtomicIntegerArray, AtomicLongArray和AtomicReferenceArray
The AtomicIntegerArray, AtomicLongArray, and
AtomicReferenceArray classes further extend atomic operation
support to arrays of these types. These classes are also notable
in providing volatile access semantics for their array elements,
which is not supported for ordinary arrays.
1.4 weakCompareAndSet
The atomic classes also support method weakCompareAndSet,
which has limited applicability. On some platforms, the weak
version may be more efficient than compareAndSet in the normal
case, but differs in that any given invocation of the
weakCompareAndSet method may return false spuriously (that is,
for no apparent reason). A false return means only that the
operation may be retried if desired, relying on the guarantee that
repeated invocation when the variable holds expectedValue and
no other thread is also attempting to set the variable will
eventually succeed. (Such spurious failures may for example be
due to memory contention effects that are unrelated to whether
the expected and current values are equal.) Additionally
weakCompareAndSet does not provide ordering guarantees that
are usually needed for synchronization control. However, the
method may be useful for updating counters and statistics when
such updates are unrelated to the other happens-before
orderings of a program. When a thread sees an update to an
atomic variable caused by a weakCompareAndSet, it does not
necessarily see updates to any other variables that occurred
before the weakCompareAndSet. This may be acceptable when,
for example, updating performance statistics, but rarely
otherwise.
weakCompareAndSet适用性有限。在某些平台上,弱版本可能比普通情况下的compareAndSet更高效,但不同之处在于,任何给定的weakCompareAndSet方法调用都可能虚假地返回false(没有明显的原因)。错误返回仅表示如果需要可以重试操作,依赖于如下保证:当变量保持expectedValue时没有其他线程尝试设置变量,重复调用最终会成功。(例如,这种虚假故障可能是由于与预期值和当前值相等无关的内存争用效应。)另外,weakCompareAndSet不提供同步控制通常需要的排序保证。然而,该方法对于更新计数器和统计数据可能是有用的,当这些更新与其他程序的happens-before顺序无关时。当线程看到由weakCompareAndSet引起的原子变量更新时,它不必一定得看到在weakCompareAndSet之前发生的任何其他变量的更新。这在某些情况下是可接受的,例如更新性能统计信息,在其他情况下很少。
1.5 关联标记AtomicMarkableReference和AtomicStampedReference
The AtomicMarkableReference class associates a single boolean
with a reference. For example, this bit might be used inside a
data structure to mean that the object being referenced has
logically been deleted. The AtomicStampedReference class
associates an integer value with a reference. This may be used
for example, to represent version numbers corresponding to
series of updates.
AtomicMarkableReference类将单个布尔值与引用相关联。该位可在数据结构中表示被引用的对象在逻辑上是否已被删除。 AtomicStampedReference类将整数值与引用相关联。可用于表示与一系列更新相对应的版本号。
1.6 注意事项
Atomic classes are designed primarily as building blocks for
implementing non-blocking data structures and related
infrastructure classes. The compareAndSet method is not a
general replacement for locking. It applies only when critical
updates for an object are confined to a single variable.
Atomic classes are not general purpose replacements for
java.lang.Integer and related classes. They do not define
methods such as equals, hashCode and compareTo. (Because
atomic variables are expected to be mutated, they are poor
choices for hash table keys.) Additionally, classes are provided
only for those types that are commonly useful in intended
applications. For example, there is no atomic class for
representing byte. In those infrequent cases where you would like
to do so, you can use an AtomicInteger to hold byte values, and
cast appropriately. You can also hold floats using
Float.floatToRawIntBits(float) and Float.intBitsToFloat(int)
conversions, and doubles using
Double.doubleToRawLongBits(double) and
Double.longBitsToDouble(long) conversions.
- 原子类主要设计为用于实现非阻塞数据结构和相关基础结构类的构建块。 compareAndSet方法不是锁的通用替代方法。仅当对象的关键更新仅限于单个变量时,它才适用。
- 原子类不是java.lang.Integer和相关类的通用替换。它们没有定义equals,hashCode和compareTo等方法。 (因为预期原子变量会发生变化,所以它们不适用于作为哈希表的键。)
- 另外,只为那些常用的类型提供了对应的原子类。在某些罕见需要使用其他类型的原子类时,可使用这些类进行类型转换。
Float.floatToRawIntBits(float);Float.intBitsToFloat(int)
Double.doubleToRawLongBits(double);Double.longBitsToDouble(long)
2.消耗对比
对于CPU的消耗来说,其从小到大依次为:
- long: 最小, 多线程不安全
- volatile long: 消耗 > long, 多线程读取安全,但无法进行原子操作
- AtomicLong:消耗 > volatile long,多线程读安全,可进行原子操作
- AtomicLongFieldUpdate:消耗 > AtomicLong,因为其使用反射技术,多线程安全和可原子操作
3.AtomicReferenceFieldUpdater, AtomicIntegerFieldUpdater及AtomicLongFieldUpdater弱保证性
Note that the guarantees of the compareAndSet method in this
class are weaker than in other atomic classes. Because this class
cannot ensure that all uses of the field are appropriate for
purposes of atomic access, it can guarantee atomicity only with
respect to other invocations of compareAndSet and set on the
same updater.
请注意,此类中compareAndSet方法的保证比其他原子类弱。 因为此类无法确保该字段的所有使用都适用于原子访问的目的,只能保证相同updater上执行CAS和set操作的原子性,因此它的原子性是弱于AtomicLong的。
AtomicLong是对long型属性加了一层原子引用,任何想要修改该long值的操作都需要先获得该原子引用,而updater不会为属性增加原子引用,它是通过反射技术,通过外部操作去修改long型属性值,因此它的原子保证也是通过外部限制的,因此只能保证同一updater进行CAS和set的原子性。
网友评论