問題整理----Java原子操作類

https://www.cnblogs.com/senlinyang/p/7856339.html

1.介紹

當多線程同時修改一個變量時,會出現最終結果和期望的結果不同,這就是線程不安全的更新操作,通常我們會使用synchronized來解決這個問題,synchronized能保證多線程不會同時更新變量。

從java1.5開始,jdk提供了java.util.concurrent.atomic包,這個包中的原子操作類,提供了一種用法簡單,性能高效,線程安全的更新一個變量的方式。

atomic包裏面一共提供了13個類,分爲4種類型,分別是:原子更新基本類型,原子更新數組,原子更新引用,原子更新屬性,這13個類都是使用Unsafe實現的包裝類。

2.原子更新基本類型

(1)AtomicInteger

AtomicInteger的常用方法有:

1.int addAndGet(int delta):以原子的方式將輸入的值與實例中的值相加,並把結果返回

2.boolean compareAndSet(int expect, int update):如果輸入值等於預期值,以原子的方式將該值設置爲輸入的值

3.final int getAndIncrement():以原子的方式將當前值加1,並返回加1之前的值

4.void lazySet(int newValue):最終會設置成newValue,使用lazySet設置值後,可能導致其他線程在之後的一小段時間內還是可以讀到舊的值。

5.int getAndSet(int newValue):以原子的方式將當前值設置爲newValue,並返回設置之前的舊值

(2)AtomicLong

(3)AtomicBoolean

3.原子更新數組

(1)AtomicIntegerArray

int addAndGet(int i, int delta):以原子的方式將輸入值與數組中索引爲i的元素相加

boolean compareAndSet(int i, int expect, int update):如果當前值等於預期值,則以原子方式將數組位置i的元素設置成update值。

4.原子更新引用

原子更新基本類型的AtomicInteger只能更新一個變量,如果要原子更新多個變量,就需要使用原子更新引用類型提供的類了。原子引用類型atomic包主要提供了以下幾個類:

  AtomicReference:原子更新引用類型

  AtomicReferenceFieldUpdater:原子更新引用類型裏的字段

  AtomicMarkableReference:原子更新帶有標記位的引用類型。可以原子更新一個布爾類型的標記位和引用類型。構造方法是AtomicMarkableReference(V initialRef,booleaninitialMark)

5.原子更新屬性

如果需要原子更新某個對象的某個字段,就需要使用原子更新屬性的相關類,atomic中提供了一下幾個類用於原子更新屬性:

  AtomicIntegerFieldUpdater:原子更新整形屬性的更新器

  AtomicLongFieldUpdater:原子更新長整形的更新器

  AtomicStampedReference:原子更新帶有版本號的引用類型。該類將整數值與引用關聯起來,可用於原子的更新數據和數據的版本號,可以解決使用CAS進行原子更新時可能出現的ABA問題。

  想要原子的更新字段,需要兩個步驟:

  1.因爲原子更新字段類都是抽象類,每次使用的時候必須使用靜態方法newUpdater()創建一個更新器,並且需要設置想要更新的類和屬性

  2.更新類的字段(屬性)必須使用public volatile修飾符

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