atomic 是指一個操作是不可中斷的。即使是在多個線程一起執行的時候,一個操作一旦開始,就不會被其他線程干擾。原子類說簡單點就是具有原子/原子操作特徵的類。
併發包 java.util.concurrent
的原子類都存放在 java.util.concurrent.atomic
下,如下圖所示:
根據操作的數據類型,可以將 JUC 包中的原子類分爲 4 類:
基本類型
使用原子的方式更新基本類型
- AtomicInteger:整型原子類
- AtomicLong:長整型原子類
- AtomicBoolean :布爾型原子類
數組類型
使用原子的方式更新數組裏的某個元素
- AtomicIntegerArray:整型數組原子類
- AtomicLongArray:長整型數組原子類
- AtomicReferenceArray :引用類型數組原子類
引用類型
使用原子的方式更新引用
- AtomicReference:引用類型原子類
- AtomicMarkableReference:原子更新帶有標記的引用類型。該類將 boolean 標記與引用關聯起來,本質就是它的版本號只有兩個,true 和 false, 修改的時候在這兩個版本號之間來回切換,這樣做並不能解決 ABA 的問題,只是會降低 ABA 問題發生的機率而已。
- AtomicStampedReference :原子更新帶有版本號的引用類型。該類將整數值與引用關聯起來,可用於解決原子的更新數據和數據的版本號,可以解決使用 CAS 進行原子更新時可能出現的 ABA 問題。
對象的屬性修改類型
如果需要原子更新某個對象裏的某個字段時,需要用到對象的屬性修改類型原子類。
- AtomicIntegerFieldUpdater:原子更新整型字段的更新器
- AtomicLongFieldUpdater: 原子更新長整型字段的更新器
- AtomicReferenceFieldUpdater:原子更新引用類型裏的字段的更新器
要想原子地更新對象的屬性需要兩步。第一步,因爲對象的屬性修改類型原子類(以上 3 個)都是抽象類,所以每次使用都必須使用靜態方法 newUpdater() 創建一個更新器,並且需要設置想要更新的類和屬性。第二步,更新的對象屬性必須使用 public volatile 修飾符。