java原子操作類
阿新 • • 發佈:2020-08-19
背景
Java從JDK1.5開始提供了java.util.concurrent.atomic包,這個包中的原子操作類提供了一種用法簡單,效能高效,執行緒安全地更新一個變數的方式。在Java併發比程式設計中,要想保證一些操作不被其他執行緒干擾,就需要保證原子性
1、原子更新基本型別類:
- AtomicBoolean:原子更新布林型別。
- AtomicInteger:原子更新整型。
- AtomicLong: 原子更新長整型。
以上3個類提供的方法幾乎一模一樣,所以僅以AtomicInteger為例進行詳解。
- int addAndGet(int delta):以原子方式將輸入的數值與例項中的值相加,並返回結果。
- boolean compareAndSet(int expect, int update):如果輸入的數值等於預期值,則以原子方式將該值設定為輸入的值。
- int getAndIncrement():以原子方式將當前值加1,注意這裡返回的是自增前的值。
- void lazySet(int newValue):最終會設定成newValue。
- int getAndSet(int newValue):已原子方式設定值為newValue, 並返回舊值
實列:
import java.util.concurrent.atomic.AtomicInteger; public class MyAtomicTest { public static void main(String[] arg) { AtomicInteger atomicInteger=new AtomicInteger(123); System.out.println(atomicInteger.getAndIncrement()); atomicInteger.getAndSet(345); System.out.println(atomicInteger.get()); } } 結果: 123 345 程序已結束,退出程式碼 0
2、原子更新陣列:
- AtomicIntegerArray:原子更新整形陣列。
- AtomicLongArray:原子更新長整型陣列。
- AtomicReferenceArray:原子更新引用型別數組裡的元素。
這三個類的最常用的方法是如下兩個方法:
(1)get(int index):獲取索引為index的元素值。
(2)compareAndSet(int i,E expect,E update): 如果當前值等於預期值,則以原子方式將陣列位置i的元素設定為update值。
3、原子更新引用型別:
原子更新基本型別的AtomicInteger,只能更新一個變數。如果要原子更新多個變數,就需要使用這個原子更新引用型別提供的類,包含以下三個。
- AtomicReference:原子更新引用型別
- AtomicReferenceFieldUpdater:原子更新引用型別裡的欄位
- AtomicMarkableReference:原子更新帶有標記位的引用型別。
這三個類提供的方法都差不多,首先構造一個引用物件,然後把引用物件set進Atomic類,然後呼叫compareAndSet等一些方法去進行原子操作,原理都是基於Unsafe實現,但AtomicReferenceFieldUpdater略有不同,更新的欄位必須用volatile修飾
4、原子更新欄位類:
- AtomicIntegerFieldUpdater:原子更新整型的欄位的更新器。
- AtomicLongFieldUpdater:原子更新長整型欄位的更新器。
- AtomicStampedReference:原子更新帶有版本號的引用型別。
這四個類的使用方式都差不多,示例程式碼如上一小節的AtomicReferenceFieldUpdater一樣,要想原子地更新欄位類需要兩步。第一步,因為原子更新欄位類都是抽象類,每次使用的時候必須使用靜態方法newUpdater()建立一個更新器,並且需要設定想要更新的類和屬性。第二步,更新類的欄位必須使用public volatile修飾