二、執行緒安全性
物件的狀態:儲存在狀態變數(例:例項/靜態域)中的資料。HashMap的狀態不僅儲存在物件本身,還儲存在許多Map.Entry物件中
要物件執行緒安全,需用同步機制(synchronized、volatile變數、顯式鎖、原子變數)來協同對物件可變狀態的訪問。
如果當多個執行緒訪問同一個可變的狀態變數時,沒有使用合適的同步,那麼程式就會出現錯誤.有三種方式修復這個錯誤:
1. 不線上程之間共享該狀態變數
2. 將狀態變數修改為不可變的變數
3. 在訪問狀態變數時,使用同步
ps:抽象和封裝會降低程式效能
2.1.執行緒安全類:
多個執行緒訪問時,不需額外的同步或協同,都能表現出正確的行為(行為與規範完全一致),那麼就稱這個類是執行緒安全.
無狀態的類: 不包含任何域和其他類中域的引用.臨時狀態僅存在於區域性變數中
無狀態物件一定是執行緒安全的
2.2原子性
假定有兩個操作A和B,如果從執行A的執行緒來看,當另一個執行緒執行B時,要麼將B全部執行完,要麼完全不執行B.
多個執行緒調service時,count值有偏差(實際:讀取、修改、寫入)
1) 競態條件:併發中,不恰當的執行時序,出現不正確的結果.(兩個人走岔路)
2) 複合操作
先檢查後執行; 讀取–修改–寫入等操作統稱為複合操作
當在無狀態的類中新增一個狀態時,如果該狀態完全由執行緒安全的物件來管理,這個類仍然是執行緒安全的
2.3.加鎖機制:
有了原子操作,為什麼還要採用加鎖機制?
企圖通過原子引用來實現統計每一次的輸入,原子引用本身都是執行緒安全,UnsafeCachingFactorizer 中同樣存在競態條件.無法做到同時保證兩個值同時獲取和修改.
更新變數時,需對其他變數同時控制(統一原子操作中)
要保持狀態的一致性,就需要在單個原子操作中更新所有相關的狀態變數.
1) 內建鎖(支援原子性)synchronized,相當於互斥鎖
2) 重入
如果內建鎖不可重入,下面將發生死鎖
獲取鎖的操作粒度是執行緒,而不是呼叫
JVM將記下鎖的持有者,計數器置為1,退出時,計數器遞減為0時,這個鎖將被釋放.
2.4.用鎖來保護狀態
不加區別的濫用synchronized,可能會導致程式中出現過多的同步,而且還並不足以保證複合操作都是原子的.
contains和add都是原子方法,仍存在競態條件.
2.5.活躍性與效能:
不要盲目的為了效能而犧牲簡單性(可能會破壞安全性)
當執行時間較長的計算或者無法快速完成的操作時(比如: 網路IO,控制檯IO),一定不要持有鎖
保證安全下的效能優化:
相關文章
- 執行緒安全性執行緒
- 02. 執行緒安全性執行緒
- 二. 執行緒管理之執行緒池執行緒
- 【java多執行緒】(二)執行緒停止Java執行緒
- 【多執行緒總結(二)-執行緒安全與執行緒同步】執行緒
- Java執行緒池二:執行緒池原理Java執行緒
- 多執行緒(二)執行緒
- 執行緒安全(二)執行緒
- 多執行緒的安全性問題(三)執行緒
- 多執行緒與高併發(二)執行緒安全執行緒
- python 程式、執行緒 (二)Python執行緒
- 《Java併發程式設計實戰》 第二章:執行緒安全性Java程式設計執行緒
- 走進Java Android 的執行緒世界(二)執行緒池JavaAndroid執行緒
- 【Java多執行緒】輕鬆搞定Java多執行緒(二)Java執行緒
- 多執行緒安全性和Java中的鎖執行緒Java
- JCIP閱讀筆記之執行緒安全性筆記執行緒
- 執行緒安全性保證---JMM特性詳解執行緒
- 深入解讀HashMap執行緒安全性問題HashMap執行緒
- 多執行緒筆記 二執行緒筆記
- 多執行緒學習(二)執行緒
- 探究Spring中Bean的執行緒安全性問題SpringBean執行緒
- 多執行緒程式設計基礎(二)-- 執行緒池的使用執行緒程式設計
- 多執行緒------執行緒與程式/執行緒排程/建立執行緒執行緒
- iOS 多執行緒記錄(二)iOS執行緒
- Python筆記二之多執行緒Python筆記執行緒
- 多執行緒二 基本技能執行緒
- Java多執行緒(二):Thread類Java執行緒thread
- 簡單的執行緒池(二)執行緒
- Java多執行緒的使用(二)Java執行緒
- Java多執行緒之二(Synchronized)Java執行緒synchronized
- 執行緒安全性-原子性、可見性、有序性執行緒
- C#多執行緒學習(二) 如何操縱一個執行緒C#執行緒
- Java高併發與多執行緒(二)-----執行緒的實現方式Java執行緒
- 執行緒和執行緒池執行緒
- 多執行緒--執行緒管理執行緒
- 執行緒與多執行緒執行緒
- 執行緒 執行緒池 Task執行緒
- 多執行緒【執行緒池】執行緒