併發程式設計的安全性(2)

2021-08-26 08:25:11 字數 995 閱讀 7731

安全:安全的首先是正確的且是我們預期的,

正確性:某個類的行為與其規範完全一致。

在良好的規範中通常會定義各種不變性條件來約束物件的狀態,以及定義各種後驗條件來描述物件操作的結果。我們根據這些規範在單執行緒中執行獲取正確的預期結果,代表這個程式的正確性,即所見即所知。

而當多個執行緒同時訪問某個類,這個類始終能保持其正確性,我們就認為這個類是執行緒安全的。

(無狀態物件一定是執行緒安全的)

原子性原子性指操作不被中斷,直到結束。

競態條件

某個計算的正確性取決於多個執行緒的交替執行時序,就發生了競態條件(是否正確看運氣)。

1、先檢查後執行

例如a和b相約星巴克,a到了之後看b不在,走了,剛走b來了。這個流程就發生了檢查與執行不一致。

這種觀察結果的失效就是大多數競態條件的本質-基於一種可能失效的觀察結果,做出判斷或執行某個操作。

a、延遲初始化

public class lazyinitrace 

}

a與b同時初始化lazyinitrace,a、b同時getinance操作,a已經在建立物件返回前,而b剛判斷物件為空準備執行,則結果是a、b分別得到不同的物件。而getinstance預期的是得到乙個相同的物件。

要避免競態的問題,就是要讓檢查執行成為乙個原子操作。

使用鎖來保護狀態

訪問共享狀態的復合操作,都必須是原子的,在執行復合操作的時候持有乙個鎖,可是復合操作成為乙個原子操作。

用同步來協調對某個變數的訪問,那麼在訪問該變數所在的位置上所有操作這個變數都需要同步。

每個共享的和可變的變數都應該只由同乙個鎖保護。

鎖不可濫用,且儘管將所有方法均使用鎖,也不能保證程式的安全性

if(!vector.contains(element))

vector.add(element);

vector.contains與vector.add都是原子操作,而上面只能稱之為復合操作。

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

常見問題 共享資源是否有多個執行緒同時訪問 希望結果跟預期的一致 作用 保證共享資源的可見性 如何保證可見性 hsdis工具 通過反編譯可以看到多了乙個彙編lock指令,相當於下面說的記憶體屏障的功能 硬體層面 cpu的快取記憶體 分為l1 指令快取 l2 資料快取 l3 效能逐步下降 為了最大化利...

2執行緒安全性

當多個執行緒訪問可變的同乙個狀態變數沒有正確的同步,那麼就會出現錯誤,有三種方式可以修復這種錯誤 將狀態變數修改為不可變的變數 在訪問狀態變數時使用同步 編寫併發應用程式的時候,一種準確地程式設計方式是 首先使 正確執行,然後在提高 的速度。即便如此,最好也只是當測試結果和應用需求告訴你必須提高效能...

Java併發程式設計實戰筆記二(執行緒安全性)

當多個執行緒訪問某個類時,不管執行時採用何種排程方式或者執行緒如何交替執行,主調 中不需要任何額外的同步或協同 這個類始終都能表現出正確的行為,那麼就稱這個類是執行緒安全的。執行緒安全性的根源在於多執行緒對共享變數的併發訪問出現的 有三種方式可以修復這個問題 將狀態變數修改為不可變的變數 final...