二、多線程存在的問題

多線程存在的問題

多線程運用得好可以大大提高系統的性能。但是使用不當也會對系統造成毀滅性災難。

  1. 線程安全問題。多個線程操作共享數據時,會產生線程安全問題。導致讀取髒數據或者丟失更新等問題
  2. 線程活性問題。由於程序問題導致一個線程一直處於非Runnable狀態或者處於Runnable狀態但執行的任務沒有緊張稱爲線程活性問題。例如:兩個線程,線程1需要先佔用鎖1,再佔用鎖2。線程2需要先佔用鎖2,再佔用鎖1。這是如果線程1佔用了鎖1,線程2佔用了鎖2。他們都佔用了對方需要的鎖,雙方都阻塞等待對方的鎖釋放,導致死鎖。
  3. 上下文切換。線程切換引起的上下文切換,會增加系統消耗。

線程安全問題

線程安全問題是多個線程在操作共享數據引起的。要保證線程安全,就需要保證對共享數據的操作有三個性質:原子性,可見性和有序性。

原子性

原子性是指涉及共享數據的操作對別的線程是不可分割的。即其他線程只能看到該操作未發生或者已經結束。

注意 i++ 並不是原子性操作,i++實際上是一個`read-modify-write`操作。
1. 先讀取出i的值
2. 修改i的值
3. 寫回內存

可見性

可見性是指一個線程對共享數據修改後,其他線程可以看到修改後的值。

1. 由於java內存模型中,每個線程都有一個工作內存。在對共享數據進行修改和讀取時,
是先對工作內存中的數據進行操作。所以其他線程讀取的共享變量可能是髒數據,無法保證可見性。
2. 重排序導致的有序性問題也是影響可見性的重要因素。

有序性

JIT編譯器(處理器,存儲子系統也會有重排序,瞭解)爲了優化系統,會對代碼進行重排序。重排序按照as-if-serial語義,保證重排序後在單線程時運行結果是一樣的。但是多線程時,無法保證有序性。

線程安全解決方案

多線程安全問題是因爲多個線程同時操作共享變量,缺乏同步機制來協調線程間數據的訪問和活動。jdk提供了鎖,volatile關鍵字等線程同步機制

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章