假設你已經閱讀并了解和《jdk原子類AtomicXXXX(預備篇)》,基于以上的了解,現在我們一起來研讀jdk原子類。
jdk原子類的實作方式總體很類似,是以我們選擇一個比較具有代表性的AtomicLong來研讀,學習就是要做到一通百通。
AtomicLong是什麼
AtomicLong它提供了一些原子性的操作來操作Long類,十分适合在多線程、高并發情況下使用。
對Long的操作,不使用AtomicLong可不可以,答案是肯定的,不過我們在寫代碼時比較麻煩,通常做法是使用synchronized或者Lock來實作,性能還不一定是最好的,是以最優的選擇肯定是使用AtomicLong(jdk8之前是最優的,jdk8後提供了一個封裝類LongAdder,在鎖競争激烈的情況下,他的性能更優,《LongAdder與AtomicLong》中有詳細介紹 )

1:初始化VALUE變量。通過unsafe.objectFieldOffset方法擷取value記憶體位址相對于對象記憶體位址的偏移量
2:AtomicLong的value值。請注意value被volatile修飾,修飾的作用能夠保證該對象的值在多線程間是可見的。但是該修飾将使得JVM的優化失效,是以不是必須情況,不亂使用AtomicXXXX類型類。(volatile的英文意思是可變的,不穩定。因為标明是可變不穩定的,線程在每次讀取該值時候,都要到記憶體重新擷取,不以高速緩存的為準)
3:lazySet修改的值不會對其他線程立即可見,在不需要讓共享變量的修改立刻讓其他線程可見的時候,以設定普通變量的方式來修改共享狀态,可以減少不必要的記憶體屏障,進而提高程式執行的效率。
4:CAS方式傳回舊值,設定新值
5:CAS指的就是就該方法,該方法執行的邏輯是比較替換,valueOffset值和expext做對比,一緻則賦予update值,傳回true,否則傳回false
6:weakCompareAndSet的了解需要和CompareAndSet對照。
它們都是有條件的修改程式的方法。這兩個method 都要取用兩個參數 —— 在method 啟動時預期資料所具有的值,以及要把資料所設定成的值。method隻會在變量具有預期值的時候才會将它設定成新值。如果目前值不等于預期值,該變量不會被重新指派且method 傳回false。如果目前值等于預期值會傳回boolean 的true 值,在這種情況下,值會被設定成新值。這個method 的weak 形式基本上也是一樣,但是少了一項保證:如果method 傳回的是false 值(虛假沖突),該變量不會被變動,但是這并不表示現有值不是預期值。這個method 不管初始值是否為預期值都可能會無法更新該值。
7:在高并發下為了保證擷取的一個資料是最新的,而不是過期的失效資料,此處采用自旋鎖(CLH)的方式做保證,隻有prev是最新的值時,才執行替換
8:該情況類似getAndUpdate,隻是傳入的運算行數不一緻而已。LongBinaryOperator隻是一個接口而已,使用者可以繼承實作相關接口邏輯做擴充