從本課開始學習併發程式設計的內容。主要介紹併發程式設計的基礎知識、鎖、記憶體模型、執行緒池、各種併發容器的使用。
第七節 原子併發類
原子
cas
aba
大名鼎鼎的aba問題
下面用**演示乙個aba問題
public void aba()
};thread t2 = new thread() catch (interruptedexception e)
boolean success = abaint.compareandset(100, 101);
system.out.println(string.format("thread t2, abaint: %s, issuccess: %s", abaint.get(), success));}};
t1.start();
t2.start();
}
thread t1, abaint: 101
thread t1, abaint: 100
thread t2, abaint: 101, issuccess: true
aba問題的根本原因是無法判斷變數是否真正被改變過,所以解決方案是給共享變數追加狀態,用來記錄共享變數是否被修改過。
原子類
atomicboolean 原子更新布林值
atomicinteger 原子增減數字的值
atomiclong 原子更新長數字型別的值
atomicreference 原子更新引用型別的值
atomicintegerarray 原子更新數字陣列的元素
atomiclongarray 原子更新長數字陣列的元素
atomicreferencearray 原子更新引用型別陣列的元素
atomicintegerfieldupdater 原子更新類的數字型別欄位的值
atomiclongfieldupdater 原子更新類的長數字型別欄位的值
atomicreferencefieldupdater 原子更新類的引用型別欄位的值
atomicstampedreference 原子更新帶版本號的引用型別的值,可以解決aba問題
原子更新欄位的步驟:
由於原子更新欄位的類都是抽象類,使用時需要使用靜態方法newupdater()
建立更新器,並且指定要更新的類和字段
atomicintegerfieldupdaterupd = atomicintegerfieldupdater.newupdater(user.class, 'age');
要更新的字段必須是public volatile
原子類實現原子操作的基礎是cas,把操作交給硬體底層實現的原子性
下面給乙個避免aba問題的**:
public void noaba() catch (interruptedexception e)
noabaint.compareandset(100, 101, noabaint.getstamp(), noabaint.getstamp() + 1);
system.out.println(string.format("thread t1, noabaint: %s", noabaint.getreference()));
noabaint.compareandset(101, 100, noabaint.getstamp(), noabaint.getstamp() + 1);
system.out.println(string.format("thread t1, noabaint: %s", noabaint.getreference()));}};
thread t2 = new thread() catch (interruptedexception e)
system.out.println("after stamp " + noabaint.getstamp());
boolean success = noabaint.compareandset(100, 101, stamp, stamp + 1);
system.out.println(string.format("thread t2, noabaint: %s, issuccess: %s", noabaint.getreference(), success));}};
t1.start();
t2.start();
}
before stamp 0
thread t1, noabaint: 101
thread t1, noabaint: 100
after stamp 2
thread t2, noabaint: 100, issuccess: false
可以看到執行緒t2更新失敗了,由於版本號不是期望的值,所以更新失敗 java併發之原子性
詳見 url 1 原子性操作 不能被執行緒排程機制中斷的操作 對原子性變數的賦值和返回操作通常都是原子性的 原子性可以用於除了long和double之外的所有基本型別上的簡單操作 當做不可分的原子 但是jvm將64位的 long 和double變數 讀取和寫入當成是兩個分離的32位 操作來執行。2 ...
併發程式設計系列之CLH鎖
clhlock作為自旋 公平併發鎖,其實現思路較為簡單。文中使用了threadlocal結構來維護每個執行緒的當前結點 currentnode 和前驅結點 prevnode 資訊。當前執行緒通過呼叫lock 方法,在前驅結點的voliate變數lock自旋,實現對共享資源的監聽。created by...
併發控制之原子變數操作
原子變數操作是一種在執行過程中不會被打斷的操作,它是linux核心提供的一種簡單的同步機制。原子操作需要硬體的支撐,是架構相關的。原子操作包括原子整型操作和原子位操作。linux核心提供了乙個原子整型變數,其定義在include asm atomic.h檔案中,該變數的定義為 typedef str...