併發程式設計(一) 執行緒安全

2022-09-16 18:03:14 字數 1951 閱讀 3328

1、編寫執行緒安全的**,本質上就是管理對狀態的訪問,而且通常都是共享的、可變的狀態。通俗的講,乙個物件的狀態就是它的資料,儲存在狀態變數中,比如例項域或靜態域以及其他附屬物件的域等等。我們討論執行緒安全好像是關於**的,但是我們真正要做的,是在不可控制的併發訪問中保護資料

無論何時,只要多於乙個的執行緒訪問給定的狀態變數,而且其中某個執行緒會寫入該變數,此時必須使用同步來協調執行緒對該變數的訪問。

2、沒有正確同步的情況下,如果多個執行緒訪問了同一變數,你的程式就存在隱患。有3種方法修復:

不要跨執行緒共享變數

使狀態變數為不可變的

在任何訪問狀態變數的時候使用同步。

(注:一開始就設計成執行緒安全的,比後期修復更容易)

3、設計執行緒安全的類時,優秀的物件導向技術——封裝、不可變性以及明確的不變約束——會給執行緒安全帶來諸多幫助。

4、完全由執行緒安全類構成的程式未必是執行緒安全的,執行緒安全程式也可以包含非執行緒安全的類。

5、類執行緒安全:當多個執行緒訪問乙個類時,如果不用考慮這些執行緒在執行時環境下的排程和交替執行,並且不需要額外的同步以及在呼叫方法**不必作其他的協調,這個類的行為仍然是正確的,那麼這個類就是執行緒安全類。

無狀態物件用於是執行緒安全的:

@threadsafe

public class statelessfactorizer implements servlet

當向無狀態類中加入唯一的狀態元素,而這個狀態完全被執行緒安全的物件所管理,那麼新的類仍然是執行緒安全的。

多個元素狀態都是被執行緒安全的物件所管理,則新的類並不是執行緒安全的:

unsafecachingfactorizer這個類的原子引用時執行緒安全的,但是其存在競爭關係,導致執行緒不安全。其有乙個不變約束,快取在lastfactors中的各個因子的乘積應該等於快取在lastnumber中的數值,只有遵守這個不變約束,我們的servlet才是正確的。unsafecachingfactorizer破壞了這個不變約束,即使每個set呼叫都是原子的,但是我們無法保證會同時更新lastnumber和lastfactors,當某個執行緒只修改了乙個變數而另乙個變數還沒有開始修改,其他執行緒將看到servlet違反了不變約束。同樣的,當執行緒a嘗試獲取兩個值的時間裡,執行緒b已經修改了它們,執行緒a會觀察到servlet違反了不變約束。

為了保護狀態的一致性,要在單一的原子操作中更新互相關聯的狀態變數。

競爭條件:想得到正確的答案,要依賴於「幸運」的時序。 最常見的一種競爭條件是:檢查再執行(如你觀察到檔案不存在,然後取建立檔案,但事實上,從觀察到執行的這段時間,有人已經建立檔案,從而引發錯誤)

檢查再執行的常見用法是惰性初始化:延遲物件的初始化,知道程式使用它。

@notthreadsafe

class lazyinitrace

return instance;}}

兩個執行緒同時呼叫getinstance()會得到不同的結果,然而,我們期望getinstance總是返回相同的例項。

為了避免競爭條件,必須阻止其他執行緒訪問我們正在修改的變數,讓我們可以確保:當其他執行緒想要檢視或修改乙個狀態時,必須在我們的執行緒開始之前或完成之後,而不能在操作過程中。

假設操作a和操作b,如果從執行a的執行緒的角度看,當其他執行緒執行b時,要麼b全部執行,要麼一點都沒有執行,這樣a和b互為原子操作。 

7、鎖不僅僅是關於同步與互斥的,也是關於記憶體可見的。為了保證所有的執行緒都能夠看到共享的,可變變數的最新值,讀取和寫入執行緒必須使用公共的鎖進行同步。

併發程式設計專題(一) 執行緒安全問題

當多個執行緒同時共享,同乙個全域性變數或靜態變數,做寫的操作時,可能會發生資料衝突問題,也就是執行緒安全問題。但是做讀操作是不會發生資料衝突問題。案例 需求現在有100張火車票,有兩個視窗同時搶火車票,請使用多執行緒模擬搶票效果。public class threadtrain implements...

併發程式設計學習筆記(一 執行緒基礎)

1 程序 計算機資源分配的基本單位 它讓作業系統的併發成為可能。2 執行緒 計算機資源排程的基本單位 它讓程序內部的併發成為可能。3 注意點 乙個程序雖然包括多個執行緒,但是這些執行緒是共同 享有程序占有的資源和位址空間的 1 通過繼承thread建立 1 public class threadte...

執行緒安全筆記一 執行緒安全概念

個人理解 執行緒安全是指一段 或程式,在多執行緒的情況下執行時,仍然能做出所期望的結果或行為。也就是說,如果一段 或程式是單執行緒的,則他必定是執行緒安全的。換句話說,執行緒安全都是指的多執行緒。需要考慮執行緒安全的程式,必定是多執行緒的。但不是所有的執行緒安全的程式都需要考慮執行緒安全問題。只有在...