執行緒安全 執行緒安全的注意事項

2022-09-19 12:45:13 字數 1384 閱讀 8659

當在多執行緒的環境下,多個執行緒去訪問共享的快取或者物件時,同時操作會對結果造成不用程度的改變,尤其是在操作上不具備原子性的操作上時會發生這種情況,例如我們之前在【執行緒安全】 三類執行緒安全問題章節說到的i + +問題,他其實就屬於一種對共享變數訪問時,由於i + +不是原子性操作,導致結果不是預期的結果。

在回到i + +的問題上,i + +在cup執行的時候,其實也是一種執行緒安全的問題。

我們再看到這張圖,兩個執行緒都同時去執行i + +操作,由於i + +不是原子性操作,這樣就會造成第一次i + +還沒完成就被第二個執行緒拿去i + +這樣就會操作兩次執行的結果一致,但結果就不對了。其實正確的時序性的操作應該是執行緒1的i + +操作完成之後再去執行i + +的操作。

說到底,如何保證時序的操作,你就保證他這個操作的原子性就可以了,只要讓他再執行這段**的邏輯時,不會被其他的執行緒搶去執行。

這種常發生在業務**中,比如有兩個執行緒,乙個執行緒獲取學生的名字,乙個執行緒獲取執行緒的學號。如果學生的學號變了,學生的名字也會跟著變化,那麼這個時候就會容易出現其中乙個執行緒更新不及時,導致學生的名字和學號對不上。導致資料有誤。那在這種情況下,我們也是需要去保持執行緒的原子性。

這種其實在很多新手開發會發生的錯誤,在使用多執行緒時,如果使用arraylist,多個執行緒同時對它進行資料操作,那麼這個時候就會出現資料錯誤,這個原因就是因為它不是執行緒安全的,如果需要在多執行緒的環境下去操作list集合,就需要去使用copyonwritearraylist。

所以在我們日常寫多執行緒的時候,如果用到公共的方法,尤其是在會對資料進行操作上的方法,請使用執行緒安全的。

在計算機中,cup的核數其實是遠小於執行緒數的,所以cup先排程多執行緒的時候會不斷的去切換執行緒,以達到多執行緒看似在同時執行的場景。但是cup在排程執行緒的時候,會進行上下文的切換,比如執行緒1切換到執行緒2,這時就需要讀取執行緒2的快取到cpu中,此時的邏輯也會可能跟著執行緒執行的內容不容而切換執行的邏輯。而這個資源的切換其實全靠cup來完成。這樣就會多出一些效能上的消耗。

在每個執行緒切換完上下文之後,執行緒的快取可能會快取到cpu的快取記憶體中,如果當前執行緒邏輯還沒有執行完成就切換到另外乙個執行緒,那麼之前執行緒的快取就有可能失效了,那麼下次cup再次排程到這個執行緒的時候,就又需要重新讀取快取去執行。那麼這個時候也會消耗不少的效能資源。

協作開銷通常出現在我們為了執行緒安全上而做的一些操作,比如對乙個共享資源進行訪問,cup可能為了保證共享資源的準確性,會禁止cpu的指令重排序。還有可能為了出於同步的目的,反覆的把執行緒工作記憶體的資料重新整理到主存中,然後從主存中重新整理到其他執行緒的工作記憶體中,這種問題如果發生在單執行緒上將不會有這種狀態,但是處於多執行緒需要協作,同時又要避免執行緒安全的問題,就不得不採用上面的方法來犧牲效能。這樣就間接的降低了執行緒的效能。

執行緒安全 執行緒不安全

執行緒安全是針對多執行緒來講的 如果所使用的公用變數在多執行緒下沒有被保護機制時,變數結果會和理論值不一致,這就是執行緒不安全 相反公用變數在保護機制下工作,就不會出現 隨機 變化,這時叫執行緒安全。執行緒安全 在多執行緒中使用時,不用自己做同步處理 執行緒不安全 在多執行緒中使用時,必須做執行緒同...

安全執行緒佇列(二)

在之前的基礎上增加了條件變數,相比之前的等待時間減少,處理速度更快 brief cthreadsafequeue 基於鎖和條件變數的執行緒安全棧 brief 相對來說比上面設計上不需要過多的加鎖等待,速度要更快 template class ccondsafequeue public cthread...

如何保證執行緒安全(執行緒同步)

基於衝突檢測的樂觀併發策略,通俗的說,就是先進行操作,如果沒有其他執行緒爭用共享資料,那操作就成功了。cas操作 compare and swap cas指令需要3個運算元,分別是記憶體位置v 舊的預期值a和新值b。cas指令執行時,當且僅當v符合舊的預期值a時,處理器用新值b更新v的值,否則它就不...