學習非阻塞的同步機制CAS

2022-10-06 16:18:13 字數 2212 閱讀 8418

在研究執行緒池的執行原理時,看到一段不斷迴圈重試的**,不理解它的原理,看注釋這是cas的實現,所以學會之後記錄下來。

鎖有什麼劣勢

在多執行緒併發下,可以通過加鎖來保證執行緒安全性,但多個執行緒同時請求鎖,很多情況下避免不了要借助作業系統,執行緒掛起和恢復會存在很大的開銷,並存在很長時間的中斷。一些細粒度的操作,例如同步容器,操作往往只有很少**量,如果存在鎖並且執行緒激烈地競爭,排程的代價很大。

總結來說,執行緒持有鎖,會讓其他需要鎖的執行緒阻塞,產生多種風險和開銷。加鎖是一種悲觀rlasjoj方法,www.cppcns.com執行緒總是設想在自己持有資源的同時,肯定有其他執行緒想要資源,不牢牢鎖住資源還不能放心呢。

在硬體的支援下,出現了非阻塞的同步機制,其中一種常用實現就是cas。

什麼是cas

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

cas 操作包含三個運算元 —— 記憶體位置(v)、預期原值(a)和新值(b)。如果記憶體位置的值與預期原值相匹配,那麼處理器會自動將該位置值更新為新值。否則,處理器不做任何操作。無論v值是否等於a值,都將返回v的原值。cas 有效地說明了:我認為位置 v 應該包含值 a;如果包含該值,則將 b 放到這個位置;否則,不要更改該位置,只告訴我這個位置現在的值即可。

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

public class simulationcas

public synchronized boolean compareandset(int expectedvalue, int newvalue)

return false;

}public synchronized int compareandswap(int expectedvalue, int newvalue)

return oldvalue程式設計客棧;

}}上面的**模擬了cas的操作,其中compareandswap是cas語義的體現,compareandset對value進行了更新操作,並返回成功與否。

幾行**就實現了cas,是不是覺得很簡單呢?但你要知道,cas僅僅告訴你操作結果,操作失敗後一系列重試回退放棄等操作都要自己實現,開發起來遠比使用鎖複雜。

atom原子類

jvm是支援cas的,體現在我們常用的atom原子類,拿atomicinteger分析一下原始碼。

public final int getandincrement()

}對atomicinteger進行+1操作,迴圈裡,會將當前值和+1後的目標值傳入compareandset,直到成功才跳出方法。compareandset是不是很熟悉呢,接著來看看它的**。

// seturlasjojp to use unsafe.compareandswapint for updates

private static final unsafe unsafe = unsafe.getunsafe();

public final boolean compareandset(int expect, int update)

compareandset呼叫了unsafe.compareandswapint,這是乙個native方法,原理就是呼叫硬體支援的cas方法。看懂這個應該就能明白atom類的原理,其他方法的實現是類似的。

執行緒池裡的cas

有了cas的基礎後,可以來研究那段我未看懂的**。

提交乙個執行任務,執行緒池會嘗試增加乙個工作執行緒去處理任務。下面是threadpoolexecutor裡addworker的一段**:

private boolean addworker(runnable firsttask, boolean core)

}//其他省略

在內迴圈裡,會呼叫compareandincrementworkercount方法增加乙個工作執行緒,原理和atomicinteger的getandincrement方法是一樣的。如果增加成功,直接跳出迴圈,否則在檢查執行緒池狀態後,再次在內迴圈呼叫compareandincrementworkercount,直到新增成功。

現在再看**,瞬間就明白了。

本文標題: 學習非阻塞的同步機制cas

本文位址: /ruanjian/j**a/261300.html

認識非阻塞的同步機制CAS

原文在這裡 在研究執行緒池的執行原理時,看到一段不斷迴圈重試的 不理解它的原理,看注釋這是cas的實現,所以學會之後記錄下來。在多執行緒併發下,可以通過加鎖來保證執行緒安全性,但多個執行緒同時請求鎖,很多情況下避免不了要借助作業系統,執行緒掛起和恢復會存在很大的開銷,並存在很長時間的中斷。一些細粒度...

執行緒的同步機制

1 執行緒安全與非執行緒安全 非執行緒安全是當多個執行緒訪問同乙個物件彙總的成員變數時產生的,產生的後果就是髒讀,就是指讀到的資料是被更改過的。而執行緒安全就是對獲取成員變數的值經過同步處理,不會再出現髒讀的現象。2 執行緒不安全的產生條件 a.存在多個執行緒 b.多個執行緒共享同乙個資源 c.對共...

RTP RTCP的時間同步機制

rtp支援傳送不同codec的steaming,不同codec的clock rate的也不一樣,不同的media之間需要依靠rtcp進行同步。這裡簡單介紹一下他們的機制。在每個rtcp sr包中對應有乙個rtp時間和乙個ntp時間,它表達的意思很明確,那就是這個rtp時間對應的絕對時間,不同medi...