內存模型和線程
由於處理器的速度與存儲和通訊子系統之間的速度相差太大,所以出現了併發和緩存等技術,來減弱這種差距。
本節簡要介紹Java內存模型,volatile變量。
Java內存模型
每個線程都會保持一個工作內存,線程對於變量的操作,都在工作內存中進行,操作完成之後,再刷新至主內存。其模型如下:
內存操作:
- lock(鎖定)
- unlock(解鎖)
- read(讀取)
- load(載入)
- use(使用)
- assign(賦值)
- store(存儲)
- write(寫入)
volatile變量
兩種特性:
可見性,變量對所有線程可見;即任一線程對於變量的修改,其他線程可以觀測的到。
禁止指令重排序優化。請看代碼:
Configuration config ;
volatile boolean isInitialed = false;
//以下代碼在線程A中執行
config = new Congiguration();
isInitialed = true;
//以下代碼在線程B中執行
if(!isInitialed){
sleep();
}
doSthWithConfig();
如果不添加volatile修飾符,那麼有可能執行指令重排序優化,“isInitialed = true”可能在”config = new Configuration()“之前執行,當切換到線程B時,就會執行”doSthWithConfig()”,程序出錯。
Java併發特徵
- 原子性
- 可見性
- 併發性
先行發生原則
Java併發代碼的一些默認的發生順序,滿足先行發生原則,即不作任何約束它也會滿足的順序:
- 程序次序規則:同一線程內,書寫順序即執行順序。(疑惑:單線程也會發生指令重排序,這條規則是否只是概念性的?)
- 管程鎖定規則
- volatile變量規則
- 線程啓動規則
- 線程中斷規則
- 線程終止規則
- 對象終結規則
- 傳遞性
線程安全
- 不可變:如final,String類對象
- 絕對線程安全:大多數都不是絕對線程安全
- 相對線程安全:通常意義上的線程安全
- 線程兼容:本身不是線程安全,通過其他手段保證
- 線程對立:不能併發的代碼
結束語
由於本人知識水平有限,這本《深入理解Java虛擬機》讀了好幾遍纔敢寫這一系列博客,但還是難免有錯誤,希望大家批評指正。這本書還有許多值得學習的地方,強烈推薦,看多少遍都不爲過謝謝大家。