1 線程安全的核心在于對狀態(tài)訪問操作進行管理,尤其是共享的和可變的宪塔,所以可變對象盡量寫在run方法內部
2 synchronized/volatile/顯示鎖/原子變量?/transient
3 多個線程訪問同一個可變狀態(tài)變量時沒有合適的同步,三種方式可以同步:
(1)不在線程之間共享該狀態(tài)變量
(2)將狀態(tài)變量改為不可變的變量第步,要么final协屡,要么new一個新對象?即使對象里所有域都是final類型,對象仍然可變艘包,因為final類型的域中可以保存對可變對象的引用。final域能確保初始化過程的安全性耀盗,從而可以不受限制的訪問不可變對象想虎,并在共享這些對象時無須同步。
(3)在訪問狀態(tài)變量時使用同步
4 無狀態(tài)對象一定是線程安全的叛拷,這里的狀態(tài)指類的變量
5 當某個計算的正確性取決于多個線程的交替執(zhí)行時序時舌厨,就會發(fā)生競態(tài)條件,例如:延遲初始化
6 java.util.concurrent.atomic包包含了一些原子變量類忿薇,例如:通過用AtomicLong來代替long類型的計數器
7 要保持狀態(tài)的一致性裙椭,就要在單個原子操作中更新所有相關的狀態(tài)變量?
8 內置鎖:@GuardBy("this")
9 當計算時間較長,一定不要有鎖煌恢,例如:網絡IO或控制臺IO
10 對于非volatile類型的long和double變量骇陈,JVM允許將64位的讀寫操作分解為兩個32位的操作,所以讀寫操作在不同的線程里執(zhí)行瑰抵,可能會讀到某個值的高32位和另一個值的低32位
11 volatile的典型用法:檢查某個某個狀態(tài)標記以判斷是否退出循環(huán)你雌。可確保將變量的更新操作通知其他線程二汛。加鎖機制可同時確保內存可見性和原子性婿崭,而volatile只確保可見性肴颊。
12 this引用逸出氓栈?public getter方法會導致逸出?