線程的安全性問題體現在:
- 原子性:一個或者多個操作在 CPU 執行的過程中不被中斷的特性
- 可見性:一個線程對共享變量的修改,另外一個線程能夠立刻看到
- 有序性:程序執行的順序按照代碼的先后順序執行
導致原因: - 緩存導致的可見性問題
- 線程切換帶來的原子性問題
- 編譯優化帶來的有序性問題
解決辦法: - JDK Atomic開頭的原子類、synchronized、LOCK,可以解決原子性問題
- synchronized、volatile、LOCK,可以解決可見性問題
- Happens-Before 規則可以解決有序性問題
Happens-Before 規則如下: - 程序次序規則:在一個線程內,按照程序控制流順序,書寫在前面的操作先行發生於書寫在后面的操作
- 管程鎖定規則:一個unlock操作先行發生於后面對同一個鎖的lock操作
- volatile變量規則:對一個volatile變量的寫操作先行發生於后面對這個變量的讀操作
- 線程啟動規則:Thread對象的start()方法先行發生於此線程的每一個動作
- 線程終止規則:線程中的所有操作都先行發生於對此線程的終止檢測
- 線程中斷規則:對線程interrupt()方法的調用先行發生於被中斷線程的代碼檢測到中斷事件的發生
對象終結規則:一個對象的初始化完成(構造函數執行結束)先行發生於它的finalize()方法的開始