AtomicInteger原始碼分析

2021-07-24 17:03:58 字數 1721 閱讀 7528

最常需要解決的問題是i++ 這個語義在多執行緒中是不安全的。雖然從語法上看上去是乙個操作,實際上分為了三步。取出i的值,i+1,將i+1的計算結果賦值給i。假設i的初始值為5,一種不安全的情況如下:-1

2345

6執行緒1

i(5)

i+1(6)

i(6)

執行緒2i(5)

i+1(6)

i(6)

也就是說兩個執行緒併發執行i++操作,所得的結果都是6 !而我們期望應該是乙個是6,乙個是7。如果這個用於資料庫主鍵的生成,這將導致嚴重的主鍵衝突。

// setup to use unsafe.compareandswapint for updates

private static final unsafe unsafe = unsafe.getunsafe();

private static final long valueoffset;

static catch (exception ex)

}private volatile int value;

public final int incrementandget()

value:用volatile修飾使得變數對所有執行緒可見,代表實際值,atomicinteger.get()就是返回這個的值。

incrementandget():這是也就是我們常用的保證原子操作遞增方法,它實際上呼叫了unsafe.getandaddint()

unsafe類並不能直接檢視到原始碼,只能通過反編譯來看。

public final native boolean compareandswapint(object object, long valueoffset, int expected, int update);

public final int

getandaddint(object object, long valueoffset, int increament) while(!this.compareandswapint(object, valueoffset, expected, expected + increament));

return expected;

}

先看看compareandswapint方法,方法用native修飾,表示是乙個本地方法,呼叫的是cas指令執行,這是整個過程是乙個原子操作。功能是如果位址(由object和valueoffset共同確定)中的值與expected相同,則設定改位址的值為update,並返回true,否則不更新且返回false。

再看看getandaddint(),在這個方法中呼叫了this.getintvolatile(object, valueoffset),表示獲取位址中的值,那麼整個getandaddint()方法的語義是:

1.獲取到物件中儲存value位址的值

2.然後再回去比較是否相等,相等則更新,否則從1開始重試直到成功。

為什麼atomicinteger操作並不會出現執行緒問題:當兩個執行緒同時進入do-while迴圈中後,只有第乙個執行緒能執行更新操作成功並退出迴圈,第二個執行緒試圖執行賦值操作因為位址中的值不一致而不會更新,只能重新執行迴圈,重新執行迴圈獲得到的是最新的value值,所以此處並不會出現執行緒問題。

該類的中其它方法與本文類似,故不重複分析。

注:本文原始碼為jdk1.8

AbstractCollection原始碼分析

abstractcollection抽象類提供了collection的骨架實現,collection分析請看 這裡直接看它的 是如何實現的.public abstract iterator iterator 該方法沒有實現.public abstract int size 該方法沒有實現.publi...

ThreadPoolExecutor原始碼閱讀

執行緒池解決兩個問題 一是復用執行緒,減少建立銷毀執行緒帶來系統開銷 二是限定系統資源使用邊界,避免大量執行緒消耗盡系統記憶體 適用於互不依賴,執行時間短,不需要對執行緒控制操作的執行緒 新增任務時,1.若執行緒數量小於corepoolsize,則新增執行緒執行任務 2.若執行緒數量大於等於core...

OrangePi One Android 原始碼編譯

一 系統環境搭建參照 二 lichee原始碼編譯 1.檢視help build.sh h2.配置核心 cd linux 3.4 make arch arm menuconfig 進入配置頁面,上下移動列表,空格是選擇列表,左右移動選擇退出選項 3.首次編譯執行清除 在 lichee linux3.4...