java併發編程:線程安全管理類--原子包--java.util.concurrent.atomic

java.util.concurrent.atomic 的描述

AtomicBoolean 能夠用原子方式更新的 boolean 值。
AtomicInteger 能夠用原子方式更新的 int 值。
AtomicIntegerArray 能夠用原子方式更新其元素的 int 數組。
AtomicIntegerFieldUpdater<T> 基於反射的實用工具,能夠對指定類的指定 volatile int 字段進行原子更新。
AtomicLong 能夠用原子方式更新的 long 值。
AtomicLongArray 能夠用原子方式更新其元素的 long 數組。
AtomicLongFieldUpdater<T> 基於反射的實用工具,能夠對指定類的指定 volatile long 字段進行原子更新。
AtomicMarkableReference<V> AtomicMarkableReference 維護帶有標記位的對象引用,能夠原子方式對其進行更新。
AtomicReference<V> 能夠用原子方式更新的對象引用。
AtomicReferenceArray<E> 能夠用原子方式更新其元素的對象引用數組。
AtomicReferenceFieldUpdater<T,V> 基於反射的實用工具,能夠對指定類的指定 volatile 字段進行原子更新。
AtomicStampedReference<V> AtomicStampedReference 維護帶有整數「標誌」的對象引用,能夠用原子方式對其進行更新。

類的小工具包,支持在單個變量上解除鎖的線程安全編程。事實上,此包中的類可將 volatile 值、字段和數組元素的概念擴展到那些也提供原子條件更新操做的類,其形式以下:html

  boolean compareAndSet(expectedValue, updateValue);

若是此方法(在不一樣的類間參數類型也不一樣)當前保持 expectedValue,則以原子方式將變量設置爲 updateValue,並在成功時報告 true。此包中的類還包含獲取並沒有條件設置值的方法,以及如下描述的較弱條件的原子更新操做 weakCompareAndSetjava

這些方法的規範使實現可以使用當代處理器上提供的高效機器級別原子指令。可是在某些平臺上,該支持可能須要某種形式的內部鎖。於是,該方法不能嚴格保證不被阻塞 - 執行操做以前可能暫時阻塞線程。編程

AtomicBooleanAtomicIntegerAtomicLongAtomicReference 的實例各自提供對相應類型單個變量的訪問和更新。每一個類也爲該類型提供適當的實用工具方法。例如,類 AtomicLongAtomicInteger 提供了原子增量方法。一個應用程序將按如下方式生成序列號:api

class Sequencer {
  private final AtomicLong sequenceNumber
    = new AtomicLong(0);
  public long next() {
    return sequenceNumber.getAndIncrement();
  }
}

原子訪問和更新的內存效果通常遵循如下可變規則,正如 The Java Language Specification, Third Edition (17.4 Memory Model) 中的聲明:數組

  • get 具備讀取 volatile 變量的內存效果。
  • set 具備寫入(分配)volatile 變量的內存效果。
  • 除了容許使用後續(但不是之前的)內存操做,其自身不施加帶有普通的非 volatile 寫入的從新排序約束,lazySet 具備寫入(分配)volatile 變量的內存效果。在其餘使用上下文中,當爲 null 時(爲了垃圾回收),lazySet 能夠應用不會再次訪問的引用。
  • weakCompareAndSet 以原子方式讀取和有條件地寫入變量但 建立任何 happen-before 排序,所以不提供與除 weakCompareAndSet 目標外任何變量之前或後續讀取或寫入操做有關的任何保證。
  • compareAndSet 和全部其餘的讀取和更新操做(如 getAndIncrement)都有讀取和寫入 volatile 變量的內存效果。

除了包含表示單個值的類以外,此包還包含 Updater 類,該類可用於獲取任意選定類的任意選定 volatile 字段上的 compareAndSet 操做。AtomicReferenceFieldUpdaterAtomicIntegerFieldUpdaterAtomicLongFieldUpdater 是基於反射的實用工具,能夠提供對關聯字段類型的訪問。它們主要用於原子數據結構中,該結構中同一節點(例如,樹節點的連接)的幾個 volatile 字段都獨立受原子更新控制。這些類在如何以及什麼時候使用原子更新方面具備更大的靈活性,但相應的弊端是基於映射的設置較爲拙笨、使用不太方便,並且在保證方面也較差。安全

AtomicIntegerArrayAtomicLongArrayAtomicReferenceArray 類進一步擴展了原子操做,對這些類型的數組提供了支持。這些類在爲其數組元素提供 volatile 訪問語義方面也引人注目,這對於普通數組來講是不受支持的。 數據結構

原子類也支持 weakCompareAndSet 方法,該方法具備受限制的適用性。在某些平臺上,弱版本在正常狀況下可能比 compareAndSet 更有效,但不一樣的是 weakCompareAndSet 方法的任何給定調用可能意外 返回 false(即沒有明確的緣由)。返回 false 僅意味着能夠在須要時從新嘗試操做,具體取決於重複執行調用的保證,當該變量保持 expectedValue 而且沒有其餘線程也在嘗試設置該變量時,最終將得到成功。(例如,這樣的虛假失敗多是因爲內存爭用的結果,該爭用與指望值和當前值是否相等無關)。 此外,weakCompareAndSet 不提供一般須要同步控制的排序保證。可是,在這樣的更新與程序的其餘 happen-before 排序不相關時,該方法可用於更新計數器和統計數據。當一個線程看到對 weakCompareAndSet 致使的原子變量的更新時,它不必定能看到在 weakCompareAndSet 以前發生的對任何其餘 變量的更新。例如,在更新性能統計數據時,這也許能夠接受,但其餘狀況幾乎不能夠。oracle

AtomicMarkableReference 類將單個布爾值與引用關聯起來。例如,能夠在數據結構內部使用此位,這意味着引用的對象在邏輯上已被刪除。AtomicStampedReference 類將整數值與引用關聯起來。例如,這可用於表示與更新系列對應的版本號。app

設計原子類主要用做各類構造塊,用於實現非阻塞數據結構和相關的基礎結構類。compareAndSet 方法不是鎖的常規替換方法。僅當對象的重要更新限定於單個 變量時才應用它。工具

原子類不是 java.lang.Integer 和相關類的通用替換方法。它們 定義諸如 hashCodecompareTo 之類的方法。(由於原子變量是可變的,因此對於哈希表鍵來講,它們不是好的選擇。)另外,僅爲那些一般在預期應用程序中使用的類型提供類。例如,沒有表示 byte 的原子類。這種狀況不常見,若是要這樣作,可使用 AtomicInteger 來保持 byte 值,並進行適當的強制轉換。也可使用 Float.floatToIntBitsFloat.intBitstoFloat 轉換來保持 float 值,使用 Double.doubleToLongBitsDouble.longBitsToDouble 轉換來保持 double 值。

相關文章
相關標籤/搜索