《Java高併發編程詳解-多線程架構與設計》線程安全與數據同步

摘自《Java高併發編程詳解-多線程架構與設計》第四章

定義

共享資源:多個線程對同一資源訪問(讀寫)
線程安全:多個線程對同一資源訪問的數據是一致的。

Synchronized使用

同步方法

同步代碼塊

深入 synchronized關鍵字

p66-67
不應該叫synchronized(mutex)爲鎖,而應該是某個線程獲取了與mutex關聯的monitor鎖。

當使用synchronize鎖住某段代碼, 幾個線程一起去訪問時。使用jstack查看堆棧時可以發現,只有一個線程持有鎖locked,其他線程處於由於AccessResource被阻塞處於BLOCKED狀態。

使用jvm命令 javap對文中的Mutex Class反編譯可以發現 monitor enter 與 monitor exit
成對出現。

在這裏插入圖片描述

使用synchronized注意的問題

  1. 與monitor關聯的對象不能爲null

  2. synchronized的作用域不要太大

  3. 不同的monitor交叉使用時,保證順序一致,否則容易死鎖
    ps:可以使用jstack pid 查看死鎖

     methodA(){ 
     		synchronized(A)
     			synchronized(B)
     			}
     methodB(){
     		synchronized(B)
     			synchronized(A)
     			}
    

    解決方法:保證順序一致即可。

4.容易死鎖的原因

  1. 交叉鎖的使用

  2. 內存不足
    當線程1,2都需要30M的內存,但是線程1申請了10M了,線程2申請了20M,彼此都在等待對方的資源釋放。

  3. 一問一答的數據交換
    服務端等待客戶端的請求,但是某種原因導致錯過了。結果服務端就一直等待。 ps:客戶端也是。
    4 .數據庫鎖

  4. 文件鎖
    某個線程獲取了文件鎖意外退出,其他讀取該文件的線程會死鎖直到系統釋放該文件的句柄。

  5. 死循環
    使用就stack不會出現死鎖的情況,但是CPU會飆升。

死鎖檢測

  1. 交叉鎖引起的死鎖可以通過jstack pid查看

  2. 死循環引起的死鎖(假死)
    可以用jstack jconsole、jvisualvm查看 某個線程長時間處於runnable的狀態

發佈於2019年7月7日 16:40:31

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