- 資訊首頁(yè) > 開(kāi)發(fā)技術(shù) >
- Java CAS機制的一些理解
public class test { private static int x; public static void main(String[] args) throws InterruptedException { Thread task1 = new Thread(){ @Override public void run() { super.run(); for (int i=0; i<1000; i++){ x=x+1; } } }; Thread task2 = new Thread(){ @Override public void run() { super.run(); for (int i=0; i<1000; i++){ x=x+1; } } }; task1.start(); task2.start(); task1.join(); task2.join(); System.out.println(x); } /* 1006 *///:~
兩個(gè)線(xiàn)程同時(shí)開(kāi)啟,累加x,理想的情況下,輸出應該是2000,但是最終是1006,因為是多線(xiàn)程的情況下,一次累加可能是兩個(gè)線(xiàn)程同時(shí)完成的。
public class test { private static AtomicInteger atomicInteger = new AtomicInteger(); public static void main(String[] args) throws InterruptedException { Thread task1 = new Thread(){ @Override public void run() { super.run(); for (int i=0; i<1000; i++){ atomicInteger.incrementAndGet(); } } }; Thread task2 = new Thread(){ @Override public void run() { super.run(); for (int i=0; i<1000; i++){ atomicInteger.incrementAndGet(); } } }; task1.start(); task2.start(); task1.join(); task2.join(); System.out.println(atomicInteger.get()); } }/* 2000 *///:~
修改被累加對象x為AtomicInteger,最終結果是理想的2000。在此操作中并沒(méi)有使用鎖,原因是 AtomicInteger引入了CAS機制。
CAS機制簡(jiǎn)單的說(shuō)就是,比較交換,有預期值、舊值和內存位置;取出舊值,交換新值。
源碼:
private static final long valueOffset; ... public final int incrementAndGet() { return unsafe.getAndAddInt(this, valueOffset, 1) + 1; } ... Unsafe public final int getAndAddInt(Object var1, long var2, int var4) { int var5; do { var5 = this.getIntVolatile(var1, var2); } while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4)); return var5; }
unsafe提供了硬件級別的原子操作 valueOffset是變量?jì)却娴刂?從源碼可以看出,incrementAndGet是調用了unsafe.getAndAddInt,它是一種基于CAS機制實(shí)現的,var5是從主內存中獲取最新當前值,而這個(gè)值是所有線(xiàn)程都可見(jiàn)和共享的,與var4相加交換,如果失敗就一直自旋,直到更新值成功。
可以看出來(lái),CAS沒(méi)有使用了任何鎖,就完成了線(xiàn)程安全。 CAS的優(yōu)點(diǎn)很多,但是缺點(diǎn)也很多,比如ABA問(wèn)題
其實(shí)很好理解,A->B->A,A值雖然沒(méi)有變,但是已經(jīng)經(jīng)過(guò)了某種操作。
圖解
上面的線(xiàn)程1、2、3都完成它們自己的任務(wù),并沒(méi)有問(wèn)題。但是如果它們是在轉賬,問(wèn)題就打了,賬戶(hù)就無(wú)端端的不見(jiàn)了10塊錢(qián)。
引入版本號,可以解決問(wèn)題,每次有相同的值時(shí),做一次版本累加,只要是版本號對不上就是被修改過(guò)
優(yōu)點(diǎn): 在并發(fā)量不是很高的情況,避免了鎖帶來(lái)的消耗
缺點(diǎn):
以上就是Java CAS機制的一些理解的詳細內容,更多關(guān)于Java CAS機制的資料請關(guān)注腳本之家其它相關(guān)文章!
免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng )、來(lái)自互聯(lián)網(wǎng)轉載和分享為主,文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權請聯(lián)系QQ:712375056 進(jìn)行舉報,并提供相關(guān)證據,一經(jīng)查實(shí),將立刻刪除涉嫌侵權內容。
Copyright ? 2009-2021 56dr.com. All Rights Reserved. 特網(wǎng)科技 特網(wǎng)云 版權所有 珠海市特網(wǎng)科技有限公司 粵ICP備16109289號
域名注冊服務(wù)機構:阿里云計算有限公司(萬(wàn)網(wǎng)) 域名服務(wù)機構:煙臺帝思普網(wǎng)絡(luò )科技有限公司(DNSPod) CDN服務(wù):阿里云計算有限公司 中國互聯(lián)網(wǎng)舉報中心 增值電信業(yè)務(wù)經(jīng)營(yíng)許可證B2
建議您使用Chrome、Firefox、Edge、IE10及以上版本和360等主流瀏覽器瀏覽本網(wǎng)站