線程安全:當多個線程訪問某個類時,這個類始終都能表現出正確的行爲。
1.髒讀
在setValue的時候加鎖,最好在getValue的時候加鎖,防止髒讀。
引入ACID問題:
oracle一致性讀 --undo:在做DML操作時,會把原先的值放在undo裏,如果操作失敗會roolback。
A查詢一個1000W的數據查詢時間中B在修改這個需要查詢的值並修改成功,那麼A讀到這個值得時候undo如果有變化那麼會去讀undo的值,如果undo的值被修改多次即有多個客戶端修改這個A查詢的值,那麼A會得到一個SNAPSHOT TOO OLD報錯。
2、重入
1、相互調用
2、父子類中都用synchronized修飾了,是線程安全的,否則不安全。
3、遇到異常 記錄日誌continue或者當多個任務作爲一個業務則可以報runtime異常跳出
BEGIN-END exception 記錄日誌
4、儘量不要用String常量作爲鎖,可以用New String(..)、用常量鎖的時候,儘量不在要執行的時候修改鎖內容、在用對象作爲鎖的時候,對象發生變化不影響鎖。
volatile關鍵字 private volatile int num=...
線程執行流程圖
volatile只能保證線程之間可見,不能保證原子性,要保證原子性需要使用automic類(automicInteger..),但是不能保證多個automic的原子性,需要加synchronized.
5、wait釋放鎖,notify不釋放鎖。當使用wait和notify的時候需要配合synchronized
wait和notify模擬阻塞隊列:
運行結果:
"檢查再運行"操作(如惰性初始化)和讀-改-寫操作(如自增)必須是原子性操作才能保證線程安全。
在不使用synchronized的時候可以選擇使用已有的線程安全類
活躍度與性能 保證安全的同時保證併發量