1. 程式人生 > >java 多執行緒開發注意事項

java 多執行緒開發注意事項

多執行緒開發的三大特性

  • 有序性
  • 可見性
    • 對修改後的資料可以看到擁有可見性
  • 原子性
    • 程式碼在執行的時候必須一次執行完,一次成功或者是一次失敗,一次執行緒對一段程式碼有掌控,就像事務裡面的原子一樣

執行緒,本地記憶體你,駐村互動圖

執行緒,記憶體互動圖

在jvm中的三大特性

有序性
編譯器會對程式碼以及指令進行編譯重排.
1. 編譯器優化重排
2. 指令集重排
3. 記憶體系統重排
經過三次重新排序經生成最終的指令集.
在單執行緒的執行過程中,編譯器的重排不會導致結果發生變化.

有序性編排

可見性
jvm在執行多執行緒的時候會將駐村中的變數拿到執行緒中的記憶體中,如果線上程不安全的情況下,A執行緒在對變數進行更改的時候B執行緒並不知道,B執行緒會執行自己的更改,在這種情況下就是操作不可見.

方法可見性

原子性
一個操作是不可終端的,及時在多執行緒的環境下,一個操作開始就不會被其他執行緒影響.
下圖中只有語句一是原子性操作

原子性操作

通過加鎖的形式來保證執行緒安全

正常情況下兩個執行緒是交替的執行,如果我們加鎖兩個執行緒在執行的時候就是序列的.

JMM定義記憶體訪問規範

通過JMM定義記憶體訪問規範,實現有序性可見性,原子性.

  • 程式順序原則
  • 鎖規則
  • volatile變數規則
  • 傳遞性規則,A先發生於B,B先發生於C那麼A必然先於C
  • 執行緒啟動規則
    • 會先呼叫執行緒啟動中的內容
  • 執行緒的終止
  • 執行緒中斷規則
  • 物件中介規則

JMM規範

通過滿足上面的條件來避免加鎖

執行緒安全的基本概念

什麼是執行緒安全?
當過多個執行緒訪問某個類是,不管執行時環境採用何種類,排程方式或者這些執行緒將如何交替執行,並且在主要呼叫程式碼中不需要任何額外的同步活協同,這個類都能表現出正確的行為,那麼這個類就是執行緒安全的.
通過加鎖而實現的執行緒安全不能叫做執行緒安全.

同步機制

  • 監視器所(synchronized)
  • 顯示鎖(ReentrantLock,ReadWriteLock)
  • 原子變數(atomicInteger,atomicLong,AtomicBollean)
  • Volatile
    • 在使用的時候一定要注意使用原子操作

執行緒同步機制

note
經過jvm的優化在1.5版本之後synchronized效能已經高於顯示鎖了
- 增加了自旋鎖等優化模式
自旋鎖實現原理

問題:遇到同步問題如何選擇具體的實現方式
舞曲:Synchronized是解決一切併發問題的最佳選擇

共享的和可變的變數

保證共享使用的變數在一個執行緒中就可以保證執行緒安全.

執行緒封閉技術

當訪問共享的可變資料時,通常需要同步.一種避免同步的方式就是不共享資料.如果僅在單執行緒內訪問資料,就不需要同步,這種技術成為執行緒封閉.

將屬性設定為不可變變數

當物件滿足一下條件是才是不可變的:
物件建立後不可修改
物件所有的與都是final
最佳方案:使用執行緒安全物件是實現執行緒安全的最佳方法.java.util.concurrent