天天看點

java 原子性int_Java并發程式設計之原子操作類

原标題:Java并發程式設計之原子操作類

原子操作類簡介

當更新一個變量的時候,多出現資料争用的時候可能出現所意想不到的情況。這時的一般政策是使用synchronized解決,因為synchronized能夠保證多個線程不會同時更新該變量。然而,從jdk 5之後,提供了粒度更細、量級更輕,并且在多核處理器具有高性能的原子操作類。因為原子操作類把競争的範圍縮小到單個變量上,這可以算是粒度最細的情況了。

原子操作類相當于泛化的volatile變量,能夠支援原子讀取-修改-寫操作。比如AtomicInteger表示一個int類型的數值,提供了get和set方法,這些volatile類型的變量在讀取與寫入上有着相同的記憶體語義。原子操作類共有13個類,在java.util.concurrent.atomic包下,可以分為四種類型的原子更新類:原子更新基本類型、原子更新數組類型、原子更新引用和原子更新屬性。

下面将分别介紹這四種原子操作類。

原子更新基本類型

使用原子方式更新基本類型,共包括3個類:

AtomicBoolean:原子更新布爾變量

AtomicInteger:原子更新整型變量

AtomicLong:原子更新長整型變量

具體到每個類的源代碼中,提供的方法基本相同,這裡以AtomicInteger為例進行說明。AtomicInteger提供的部分方法如下:

java 原子性int_Java并發程式設計之原子操作類

為了說明AtomicInteger的原子性,這裡代碼示範多線程對一個int值進行自增操作,最後輸出結果,代碼如下:

java 原子性int_Java并發程式設計之原子操作類

輸出結果如下:

java 原子性int_Java并發程式設計之原子操作類

可以看到在多線程的情況下,得到的結果是正确的,但是如果僅僅使用int類型的成員變量則可能得到不同的結果。這裡的關鍵在于getAndIncrement是原子操作,那麼是如何保證的呢?

getAndIncrement方法的源碼如下:

java 原子性int_Java并發程式設計之原子操作類

到這裡可以發現最終調用了native方法來保證更新的原子性。

原子更新數組

通過原子更新數組裡的某個元素,共有3個類:

AtomicIntegerArray:原子更新整型數組的某個元素

AtomicLongArray:原子更新長整型數組的某個元素

AtomicReferenceArray:原子更新引用類型數組的某個元素

AtomicIntegerArray常用的方法有:

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

boolean compareAndSet(int i, int expect, int update):如果目前值等于預期值,則以原子方式更新數組中索引為i的值為update值

示例代碼如下:

java 原子性int_Java并發程式設計之原子操作類

運作結果是:

java 原子性int_Java并發程式設計之原子操作類

數組value通過構造的方式傳入AtomicIntegerArray中,實際上AtomicIntegerArray會将目前數組拷貝一份,是以在數組拷貝的操作不影響原數組的值。

原子更新引用類型

需要更新引用類型往往涉及多個變量,早atomic包有三個類:

AtomicReference:原子更新引用類型

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

AtomicMarkableReference:原子更新帶有标記位的引用類型。

下面以AtomicReference為例進行說明:

java 原子性int_Java并發程式設計之原子操作類
java 原子性int_Java并發程式設計之原子操作類
java 原子性int_Java并發程式設計之原子操作類

可以看到user被成功更新。

原子更新字段類

如果需要原子更新某個類的某個字段,就需要用到原子更新字段類,可以使用以下幾個類:

AtomicIntegerFieldUpdater:原子更新整型字段

AtomicLongFieldUpdater:原子更新長整型字段

AtomicStampedReference:原子更新帶有版本号的引用類型。

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

每次必須使用newUpdater建立一個更新器,并且需要設定想要更新的類的字段

更新類的字段(屬性)必須為public volatile

下面的代碼示範如何使用原子更新字段類更新字段:

java 原子性int_Java并發程式設計之原子操作類

輸出的結果如下:

至此,我們知道了如何使用原子操作類在不同場景下的基本用法。傳回搜狐,檢視更多

責任編輯: