執行緒安全性(第二章)

優惠碼發放發表於2017-12-01

執行緒安全性

要編寫執行緒安全的程式碼,其核心在於要對狀態訪問操作進行管理,特別是對共享的(Shared)和可變的(Mutable)狀態的訪問。

  • 物件的狀態:儲存在狀態變數(例如例項或靜態域)中的資料,包括其他以來物件的域
  • 共享(Shared):意味著變數可以由多個執行緒同時訪問
  • 可變(Mutable):變數的值在其生命週期內可以發生變化

一個物件是否需要使執行緒安全的,取決於它是否被多個執行緒訪問。這指的是在程式中訪問物件的方式,而不是物件要實現的功能。要使得物件是執行緒安全的,需要採用同步機制來協同對物件可變狀態的訪問。如果無法實現協同,那麼可能會導致資料破壞以及其他不該出現的結果。

1. 什麼是執行緒安全性:

線上程安全性的定義中,最核心的概念就是正確性。當多個執行緒訪問某個類時,這個類始終都能表現出正確地行為,那麼就稱這個類是執行緒安全的。

  • 執行緒安全性特例:無狀態類一定是執行緒安全的

2. 原子性

  • 競態條件(Race condition):由於不恰當的執行時序而出現不正確地結果

        最常見的靜態條件就是“先檢查後執行”(可能導致通過一個失效的觀測結果來決定下一步的動作)
    
    *不要將“競態條件”與“資料競爭”相混淆,資料競爭是指,如果在訪問共享的非final型別的域沒有采用同步來進行協同,那麼就會出現資料競爭。*
    

要保持狀態的一致性,就需要在單個原子操作中更新所有相關的狀態變數。

3.加鎖機制

Java中的內建鎖(synchronized)是可重入的,即已獲得鎖的執行緒可以再次獲得這個鎖。
對於可能被多個執行緒同時訪問的可變狀態變數,在訪問它時都需要持有同一個鎖,在這種情況下,我們稱狀態變數是由這個鎖保護的。
一種常見的錯誤認為:只有在寫入共享變數時才需要使用同步。這是錯誤的。


相關文章