原子操作類-總結

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章