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的原子性。