第二章 線程安全性
- 對象的狀態(tài):存儲在狀態(tài)變量(實例或者靜態(tài)域)中的數(shù)據(jù)拴事。
- 共享:變量可以被多個線程同時訪問脓规。
- 可變:變量的值在其生命周期內(nèi)可以發(fā)生變化源织。
- 線程安全:多個線程訪問某個類的時,這個類始終都能表現(xiàn)出正確的行為誉己,那么就稱這個類是線程安全的眉尸。
- 實現(xiàn)線程安全:
1.不在線程之間共享變量的狀態(tài) - 不共享
2.將狀態(tài)變量修改為不可變的變量 - 不可變
3.在訪問狀態(tài)變量時使用同步 - 同步 - 同步機制包含:
1.synchronized
2.volatile
3.顯式鎖
4.原子變量 - 競態(tài)條件:不恰當?shù)膱?zhí)行時序出現(xiàn)不正確的結(jié)果。
- 不變性條件巨双。驗證程序是否滿足最基本的正確性噪猾。
- 要保持狀態(tài)的一致性,就需要在單個原子操作中更新所有相關(guān)的狀態(tài)變量筑累。
- 重入:一個線程請求其他線程持有的鎖會失敗袱蜡,請求本線程持有的鎖會成功。synchronized和reentrantLock都是可重入的慢宗。
- 活躍性和性能問題:降低鎖粒度
第三章 對象的共享
- 可見性:一個線程對變量的修改坪蚁,其他線程不一定能訪問到改修改。需要對變量做同步才可以保證可見镜沽。
- 在沒有同步的情況下敏晤,編譯器、處理器以及運行時等都可能對操作的執(zhí)行順序進行一些意想不到的調(diào)整缅茉。在缺乏足夠同步的多線程程序中嘴脾,要想對內(nèi)存操作得當執(zhí)行順序進行判斷,幾乎無法得出正確的結(jié)論。 個人總結(jié):編譯器會進行優(yōu)化译打,指令重排序等耗拓,需要設(shè)置內(nèi)存屏障來保證必要的指令不會被重排序。java中有一堆happends before規(guī)則奏司。
- 只要有數(shù)據(jù)在多個線程之間共享乔询,就使用正確的同步。
- 失效數(shù)據(jù):沒有使用正確的同步的情況下韵洋,一個線性沒有讀到其他線程對變量的修改哥谷。
- 64位變量和最低安全性:最低安全性:雖然讀到的變量值可能會失效,但是確實是其他線程設(shè)置過得麻献。long這些可能讀到不同版本的高32位和低32位。
- 發(fā)布:是對象能夠在當前作用域之外的代碼中使用猜扮。
- 逸出:某個不應該發(fā)布的對象被發(fā)布勉吻。
- ThisEscape:this指針逃逸,在構(gòu)造函數(shù)調(diào)用外部方法旅赢,或者起一個線程之類的齿桃。
- 線程封閉:不共享可變數(shù)據(jù)。threadlocal煮盼。
- 棧封閉:局部變量短纵。
- 不變性:不可變對象,Immutable Object僵控。
1.對象創(chuàng)建之后狀態(tài)不可修改
2.所有的域都是final
3.對象是正確創(chuàng)建的香到。 - Final域:final字段不可修改,但是final字段如果是引用類型报破,引用的對象的狀態(tài)是可以修改的悠就。java內(nèi)存模型中,final有特殊的語義充易,final能保初始化過程的安全性梗脾。。盹靴。不太理解
java 封裝的一個院子操作:unsafe.compareAndSwapInt