国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計 > 正文

【Java并發(fā)編程實(shí)戰(zhàn)】-----“J.U.C”:CAS操作

2019-11-14 14:53:24
字體:
供稿:網(wǎng)友

CAS,即Compare and Swap,中文翻譯為“比較并交換”。

對于JUC包中,CAS理論是實(shí)現(xiàn)整個java并發(fā)包的基石。從整體來看,concurrent包的實(shí)現(xiàn)示意圖如下:

201511040000·

i++是一個非常經(jīng)典的操作,它幾乎充斥著我們每個人編寫的代碼中。我們知道i++是可以分解的,它分解為getI()、i + 1 、setI三個步驟,所以它并不是原子操作。如果i==1,執(zhí)行兩次i++操作,我們期望的結(jié)果是3,但是結(jié)果有可能也是2:

2015110500001

那么有什么辦法解決這個問題呢?肯定有!使用鎖即可:

synchronized(this){            i++;        }

誠然,在java中存在樂觀鎖、悲觀鎖兩種鎖。其中synchronized就是悲觀鎖,在前面我們了解synchronized也是獨(dú)占鎖,加入關(guān)鍵字synchronized的代碼一般都是以單線程的形式在運(yùn)行著,它會導(dǎo)致其他需要該資源的線程掛起直到前面的線程執(zhí)行完畢釋放資源,所以它的效率較為低下。而樂觀鎖則采用了一種較為高效的方式,它的操作與synchronized不同,synchronized采用加鎖,而它則不采用加鎖去執(zhí)行某些操作,如果發(fā)生了沖突則失敗并一直重試直到成功為止。而CAS就是一種樂觀鎖,它所采用的策略是當(dāng)且僅當(dāng)預(yù)期值A(chǔ)和存中的值V相同,則將內(nèi)存V值修改為B,否則返回V。實(shí)現(xiàn)如下:

for(;;){            if(A==V){                V = B;            }        }

當(dāng)然在J.U.C中實(shí)現(xiàn)CAS沒有這么簡單。

CAS

CAS,即一種對內(nèi)存中的共享數(shù)據(jù)進(jìn)行操作的指令,而且該操作是原子的讀寫操作。其過程如下:首先CPU將內(nèi)存中的將要被修改的數(shù)據(jù)與預(yù)期的值進(jìn)行比較,如果這兩個值相等,CPU則會將內(nèi)存中數(shù)值替換為新值,否則不做操作。最后,CPU會將舊值返回。在java中,CAS的含義就是“我認(rèn)為的原本的值是什么,如果你是,則更換為新值,否則不做修改同時麻煩告訴我該值時多少”

在CAS中,總共存在三個操作數(shù):預(yù)期值A(chǔ)、內(nèi)存中的V、修改的值B。當(dāng)且僅當(dāng)預(yù)期值A(chǔ)和內(nèi)存中的值V相同,則將內(nèi)存V值修改為B,否則返回V。使用這種機(jī)制編寫的算法也叫作非阻塞算法,標(biāo)準(zhǔn)定義了一個線程的失敗或者掛起是不會影響其他線程的失敗或者掛起。

下面我們來已AtomicIneger的源碼為例來看看CAS操作:

public final int getAndAdd(int delta) {        for (;;) {            int current = get();            int next = current + delta;            if (compareAndSet(current, next))                return current;        }    }

這里很顯然使用CAS操作(for(;;)里面),他每次都從內(nèi)存中讀取數(shù)據(jù),+1操作,然后兩個值進(jìn)行CAS操作。如果成功則返回,否則失敗重試,直到修改成功為止。

上面源碼最關(guān)鍵的地方有兩個,一個for循環(huán),它代表著一種寧死不屈的精神,不成功誓不罷休。還有就是compareAndSet:

public final boolean compareAndSet(int expect, int update) {    return unsafe.compareAndSwapInt(this, valueOffset, expect, update);    }

CAS的缺陷

盡管CAS機(jī)制可以使我們不依賴與同步,不影響和掛起其他線程,它大大提升了運(yùn)行的效率,但是它會導(dǎo)致一個ABA的問題,如下:加入有兩個線程A、B,他們都讀取內(nèi)存中的數(shù)據(jù)V,假如這個時候線程A,先將V修改為V1,然后又修改為V,這個時候線程B的compareAndSet仍然能成功,對于線程B而言該值V并沒有發(fā)生任何變化,而實(shí)際上它已經(jīng)變化了,只不過最后又還原了而已。

 

參考文獻(xiàn)

1、Java的多線程編程模型5--Java中的CAS理論

2、JAVA CAS原理深度分析


發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 四川省| 枞阳县| 阜康市| 昌黎县| 紫阳县| 连平县| 辉南县| 手游| 鄂托克旗| 抚顺市| 罗甸县| 集贤县| 惠州市| 太仓市| 怀来县| 上栗县| 祁东县| 惠水县| 大埔县| 灌南县| 高阳县| 巴马| 定日县| 禄劝| 游戏| 兴海县| 禹州市| 安福县| 涞源县| 万年县| 肥城市| 麦盖提县| 华容县| 宜兰市| 林甸县| 盘山县| 措美县| 巩义市| 福安市| 正镶白旗| 宝鸡市|