老熟女激烈的高潮_日韩一级黄色录像_亚洲1区2区3区视频_精品少妇一区二区三区在线播放_国产欧美日产久久_午夜福利精品导航凹凸

重慶分公司,新征程啟航

為企業提供網站建設、域名注冊、服務器等服務

非阻塞的同步機制CAS怎么用

這篇文章給大家分享的是有關非阻塞的同步機制CAS怎么用的內容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。

成都創新互聯自2013年創立以來,先為伊寧等服務建站,伊寧等地企業,進行企業商務咨詢服務。為伊寧企業網站制作PC+手機+微官網三網同步一站式服務解決您的所有建站問題。

鎖有什么劣勢

在多線程并發下,可以通過加鎖來保證線程安全性,但多個線程同時請求鎖,很多情況下避免不了要借助操作系統,線程掛起和恢復會存在很大的開銷,并存在很長時間的中斷。一些細粒度的操作,例如同步容器,操作往往只有很少代碼量,如果存在鎖并且線程激烈地競爭,調度的代價很大。
總結來說,線程持有鎖,會讓其他需要鎖的線程阻塞,產生多種風險和開銷。加鎖是一種悲觀方法,線程總是設想在自己持有資源的同時,肯定有其他線程想要資源,不牢牢鎖住資源還不能放心呢。
在硬件的支持下,出現了非阻塞的同步機制,其中一種常用實現就是CAS。

什么是CAS

現代的處理器都包含對并發的支持,其中最通用的方法就是比較并交換(compare and swap),簡稱CAS。

CAS 操作包含三個操作數 —— 內存位置(V)、預期原值(A)和新值(B)。如果內存位置的值與預期原值相匹配,那么處理器會自動將該位置值更新為新值。否則,處理器不做任何操作。無論V值是否等于A值,都將返回V的原值。CAS 有效地說明了:我認為位置 V 應該包含值 A;如果包含該值,則將 B 放到這個位置;否則,不要更改該位置,只告訴我這個位置現在的值即可。

當多個線程嘗試使用CAS同時更新一個變量,最終只有一個線程會成功,其他線程都會失敗。但和使用鎖不同,失敗的線程不會被阻塞,而是被告之本次更新操作失敗了,可以再試一次。此時,線程可以根據實際情況,繼續重試或者跳過操作,大大減少因為阻塞而損失的性能。所以,CAS是一種樂觀的操作,它希望每次都能成功地執行更新操作。

public class SimulationCAS {
private int value;
public synchronized int get() {
return value;
}
public synchronized boolean compareAndSet(int expectedValue, int newValue) {
if (expectedValue == compareAndSwap(expectedValue, newValue)) {
return true;
}
return false;
}
public synchronized int compareAndSwap(int expectedValue, int newValue) {
int oldValue = value;
if (oldValue == expectedValue) {
value = newValue;
}
return oldValue;
}
}

上面的代碼模擬了CAS的操作,其中compareAndSwap是CAS語義的體現,compareAndSet對value進行了更新操作,并返回成功與否。
幾行代碼就實現了CAS,是不是覺得很簡單呢?但你要知道,CAS僅僅告訴你操作結果,操作失敗后一系列重試回退放棄等操作都要自己實現,開發起來遠比使用鎖復雜。

Atom原子類

JVM是支持CAS的,體現在我們常用的Atom原子類,拿AtomicInteger分析一下源碼。

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

對AtomicInteger進行+1操作,循環里,會將當前值和+1后的目標值傳入compareAndSet,直到成功才跳出方法。compareAndSet是不是很熟悉呢,接著來看看它的代碼。

// setup to use Unsafe.compareAndSwapInt for updates
private static final Unsafe unsafe = Unsafe.getUnsafe();
public final boolean compareAndSet(int expect, int update) {
return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}

compareAndSet調用了unsafe.compareAndSwapInt,這是一個native方法,原理就是調用硬件支持的CAS方法。看懂這個應該就能明白Atom類的原理,其他方法的實現是類似的。

線程池里的CAS

有了CAS的基礎后,可以來研究那段我未看懂的代碼。
提交一個執行任務,線程池會嘗試增加一個工作線程去處理任務。下面是ThreadPoolExecutor里addWorker的一段代碼:

private boolean addWorker(Runnable firstTask, boolean core) {
retry:
for (;;) {
int c = ctl.get();
int rs = runStateOf(c);
// Check if queue empty only if necessary.
if (rs >= SHUTDOWN &&
! (rs == SHUTDOWN &&
firstTask == null &&
! workQueue.isEmpty()))
return false;
for (;;) {
int wc = workerCountOf(c);
if (wc >= CAPACITY ||
wc >= (core ? corePoolSize : maximumPoolSize))
return false;
if (compareAndIncrementWorkerCount(c))
break retry;
c = ctl.get(); // Re-read ctl
if (runStateOf(c) != rs)
continue retry;
// else CAS failed due to workerCount change; retry inner loop
}
}

//其他省略

在內循環里,會調用compareAndIncrementWorkerCount方法增加一個工作線程,原理和AtomicInteger的getAndIncrement方法是一樣的。如果增加成功,直接跳出循環,否則在檢查線程池狀態后,再次在內循環調用compareAndIncrementWorkerCount,直到添加成功。

感謝各位的閱讀!關于“非阻塞的同步機制CAS怎么用”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!


分享標題:非阻塞的同步機制CAS怎么用
轉載注明:http://www.xueling.net.cn/article/jgheje.html

其他資訊

在線咨詢
服務熱線
服務熱線:028-86922220
TOP
主站蜘蛛池模板: 伊人久久在线?看 | 99国产精品人妻无码免费农村 | 中文字幕久久一区 | 色婷婷综合久久久久中文一区二 | 奇米777四色影视在线看 | 99国产99 | YW尤物AV无码国产在线观看 | 亚洲色综合 | 91cao在线 | 色屁屁WWW影院免费观看入口 | 精品亚洲AⅤ无码午夜在线网站 | 狼色精品人妻在线视频免费 | 韩国免费A级作爱片无码 | 少妇BWBWBWBWBWBW| 特级黄色毛片 | 久久精品国产2019国产精品 | 日本少妇高潮正在线播放 | 国产性受xxxx黑人xyx性爽 | 69热在线观看| 国产欧美精品一区二区三区小说 | 色综合久久久 | 密室大逃脱第6期免费观看 一区二区无码免费视频网站 | 国产成人亚洲精品无码青 | 国产日韩产欧美又大又黄 | 亚洲中文无码卡通动漫3D | 69av在线播放 | 奇米777国产在线视频 | 日韩AV无码AV免费AV不卡AV | 小男生自慰gay网站 国产精在线 | 精品无码免费专区毛片 | 91大神唐先生22部在线观看 | 国内一区二区三区 | 亚洲第一区在线观看 | 日产国产亚洲精品系列 | 亚洲一区精品无码 | 日本a黄色片| 国产成人精品日本亚洲18 | 黄色拍拍视频 | 久久久久亚洲av成人片仓井空 | 亚洲大码熟女在线观看 | 色欲午夜无码久久久久久 |