定義
共享資源:多個線程對同一資源訪問(讀寫)
線程安全:多個線程對同一資源訪問的數據是一致的。
Synchronized使用
同步方法
同步代碼塊
深入 synchronized關鍵字
p66-67
不應該叫synchronized(mutex)爲鎖,而應該是某個線程獲取了與mutex關聯的monitor鎖。
當使用synchronize鎖住某段代碼, 幾個線程一起去訪問時。使用jstack查看堆棧時可以發現,只有一個線程持有鎖locked,其他線程處於由於AccessResource被阻塞處於BLOCKED狀態。
使用jvm命令 javap對文中的Mutex Class反編譯可以發現 monitor enter 與 monitor exit
成對出現。
使用synchronized注意的問題
-
與monitor關聯的對象不能爲null
-
synchronized的作用域不要太大
-
不同的monitor交叉使用時,保證順序一致,否則容易死鎖
ps:可以使用jstack pid 查看死鎖
如methodA(){ synchronized(A) synchronized(B) } methodB(){ synchronized(B) synchronized(A) }
解決方法:保證順序一致即可。
4.容易死鎖的原因
-
交叉鎖的使用
-
內存不足
當線程1,2都需要30M的內存,但是線程1申請了10M了,線程2申請了20M,彼此都在等待對方的資源釋放。 -
一問一答的數據交換
服務端等待客戶端的請求,但是某種原因導致錯過了。結果服務端就一直等待。 ps:客戶端也是。
4 .數據庫鎖 -
文件鎖
某個線程獲取了文件鎖意外退出,其他讀取該文件的線程會死鎖直到系統釋放該文件的句柄。 -
死循環
使用就stack不會出現死鎖的情況,但是CPU會飆升。
死鎖檢測
-
交叉鎖引起的死鎖可以通過jstack pid查看
-
死循環引起的死鎖(假死)
可以用jstack jconsole、jvisualvm查看 某個線程長時間處於runnable的狀態
發佈於2019年7月7日 16:40:31