日本搞逼视频_黄色一级片免费在线观看_色99久久_性明星video另类hd_欧美77_综合在线视频

國內最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2
您當前位置:首頁 > 互聯網 > 聊聊高并發(十二)分析java.util.concurrent.atomic.AtomicStampedReference源碼來看如何解決CAS的ABA問題

聊聊高并發(十二)分析java.util.concurrent.atomic.AtomicStampedReference源碼來看如何解決CAS的ABA問題

來源:程序員人生   發布時間:2014-11-11 08:20:24 閱讀次數:3408次

在聊聊高并發(101)實現幾種自旋鎖(5)中使用了java.util.concurrent.atomic.AtomicStampedReference原子變量指向工作隊列的隊尾,為什么使用AtomicStampedReference原子變量而不是使用AtomicReference是由于這個實現中等待隊列的同1個節點具有不同的狀態,而同1個節點會屢次進出工作隊列,這就有可能出現出現ABA問題。


熟習并發編程的同學應當知道CAS操作存在ABA問題。我們先看下CAS操作。

CAS(Compare and Swap) 比較并交換操作是1個3元操作: 目標地址的值T(arget),期望值E(xpected),實際值R(eal),

1. 只有當目標值T == 期望值E時,才會把目標值T設置為實際值R,否則不改變目標值

2. 不管目標值是不是改變,都返回之前的目標值T


類似以下的邏輯:

package com.zc.lock; public class CAS { private int value; public synchronized int get(){ return value; } public synchronized int compareAndSwap(int expected, int real){ int oldValue = value; if(value == expected){ value = real; } return oldValue; } public synchronized boolean compareAndSet(int expected, int real){ return (expected == compareAndSwap(expected, real)); } }

CAS只比較期望值和目標值是不是相當,相當就設置新值。那末ABA問題就來了:

1. 由于CAS只是值比較,比如目標是A, 期望值也是A, 那末CAS操作會成功。但是這時候候目標A可能不是原來的那個A了,它多是A變成了B,再變成了A。所以叫ABA問題,很形象。ABA問題可能會使程序出錯,比如限時有界隊列鎖中的節點有幾個狀態,雖然援用值是A,但是可能對象的狀態已變了,這時候候的A實際已不是原來的A了

2. 需要注意的是ABA問題不是說CAS操作的進程中A變成了ABA,CAS操作是原子操作,不會被打斷。ABA問題場景以下:

先獲得了A的值,然后再CAS(A, R), 這時候候CAS中的A實際指向的對象的狀態可能和它剛取得的時候的狀態已發送了改變。


</pre><pre name="code" class="java">A a = ref.get(); // 根據a的狀態做1些操作 // do something // CAS,這時候候會出現ABA問題,a指向的對象可能已變了 ref.compareAndSet(a, b)

解決ABA問題方法就是給狀態設置時間戳,這是并發中加樂觀鎖的常見做法,如果狀態的時間戳產生了改變,證明已不是原來的對象了,所以操作失敗

// 用int做時間戳 AtomicStampedReference<QNode> tail = new AtomicStampedReference<CompositeLock.QNode>(null, 0); int[] currentStamp = new int[1]; // currentStamp中返回了時間戳信息 QNode tailNode = tail.get(currentStamp); tail.compareAndSet(tailNode, null, currentStamp[0], currentStamp[0] + 1)

下面我們來看1下java.util.concurrent.atomic.AtomicStampedReference的源代碼是如何實現的。

下面代碼來自JDK1.7,條理很清晰,實現有幾個要點:

1. 創建1個Pair類來記錄對象援用和時間戳信息,采取int作為時間戳,實際使用的時候時間戳信息要做成自增的,否則時間戳如果重復,還會出現ABA的問題。這個Pair對象是不可變對象,所有的屬性都是final的, of方法每次返回1個新的不可變對象

2. 使用1個volatile類型的援用指向當前的Pair對象,1旦volatile援用產生變化,變化對所有線程可見

3. set方法時,當要設置的對象和當前Pair對象不1樣時,新建1個不可變的Pair對象

4. compareAndSet方法中,只有期望對象的援用和版本號和目標對象的援用和版本好都1樣時,才會新建1個Pair對象,然后用新建的Pair對象和原理的Pair對象做CAS操作

5. 實際的CAS操作比較的是當前的pair對象和新建的pair對象,pair對象封裝了援用和時間戳信息


private static class Pair<T> { final T reference; final int stamp; private Pair(T reference, int stamp) { this.reference = reference; this.stamp = stamp; } static <T> Pair<T> of(T reference, int stamp) { return new Pair<T>(reference, stamp); } } private volatile Pair<V> pair; public AtomicStampedReference(V initialRef, int initialStamp) { pair = Pair.of(initialRef, initialStamp); } public void set(V newReference, int newStamp) {         Pair<V> current = pair;         if (newReference != current.reference || newStamp != current.stamp)             this.pair = Pair.of(newReference, newStamp);     } public boolean compareAndSet(V   expectedReference,                                  V   newReference,                                  int expectedStamp,                                  int newStamp) {         Pair<V> current = pair;         return             expectedReference == current.reference &&             expectedStamp == current.stamp &&             ((newReference == current.reference &&               newStamp == current.stamp) ||              casPair(current, Pair.of(newReference, newStamp)));     } private static final sun.misc.Unsafe UNSAFE = sun.misc.Unsafe.getUnsafe();     private static final long pairOffset =         objectFieldOffset(UNSAFE, "pair", AtomicStampedReference.class);     private boolean casPair(Pair<V> cmp, Pair<V> val) {         return UNSAFE.compareAndSwapObject(this, pairOffset, cmp, val);     }








生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: 国产综合区| 欧美在线国产 | 日韩高清国产一区在线 | 国产精品99久久免费观看 | 国产老女人精品毛片久久 | 91视频观看| 亚洲精品乱码久久久久久蜜桃不爽 | 金瓶狂野欧美性猛交xxxx | 欧美激情视频一区二区三区在线播放 | 午夜影院欧美 | 日本黄xxxxxxxxx100 | 久久久久久久久一区二区 | 密臀av| 日韩美女在线看免费观看 | 久久女 | av片网站 | 国产精品白浆 | 丰满少妇高潮惨叫久久久久 | 视频一区在线 | 黄色av网站在线观看 | av影片在线 | 久久九| 日韩欧美电影在线观看 | 在线日韩视频 | 成人一区二区在线 | 美日韩精品 | 国产精品久久久久一区二区 | 国产毛片精品 | 日本一区二区三区免费在线观看 | 一区二区福利 | 国产高清视频在线 | 一区二区三区日韩欧美 | 国产黄色小视频 | 国产一区久久久 | 亚洲自拍小视频 | 日本一区二区三区四区在线观看 | jizzjizz中国丰满熟少妇 | 精品美女久久久 | 日本激情网 | 国产精品久久久久久久久久免费看 | 亚洲免费精品视频 |