JAVA 死鎖分析

2021-08-22 07:16:25 字數 1110 閱讀 5249

有以下**,模擬的是兩個賬戶之間的轉賬情況

void transfer(account from,account to,int money)
單執行緒下,這段**肯定沒問題的,但在多執行緒下存在問題

現在對其加鎖,加鎖後的**如下

void transfer(account from,account to,int money)

}}

synchronized,即物件鎖,第乙個synchronized鎖住from物件,第二個synchronized鎖住to物件。

多執行緒情況下 ,在同一時刻多個執行緒中僅有乙個執行緒能拿到這個物件鎖,對物件鎖裡面的**段進行操作

但是加了物件鎖之後,可能存在死鎖!

transfer(a,b,100)和transfer(b,a,100)同時進行,即a向b轉賬的同時,b也在向a轉賬

a向b轉賬,執行緒x拿到a這個物件鎖

b向a轉賬,執行緒y拿到b這個物件鎖

操作迫切需要b這個物件鎖,才能進行轉賬操作

操作迫切需要a這個物件鎖,才能進行轉賬操作

兩個執行緒都在等待該組中的其他執行緒釋放鎖,此時發生死鎖!

從那些方面下手呢?

破除互斥等待

一般來說,我們為了程式的安全,必須給物件加上鎖,所以這個條件一般無法破除

破除hold and wait ,即占有等待

可以一次性獲取所有的資源,示例**中並不是一次性獲取from和to這兩個資源的,而是分布獲取的。

再重新嘗試獲取from與to鎖。是推薦的方法

方法二:給這段**加上乙個全域性鎖,可以保證from與to同時拿到,轉賬操作完成後,釋放這個全域性鎖。是比較安全的,但是銀行的賬戶數目眾多,轉賬操作十分頻繁,使用這種方式勢必會造成效能的嚴重下降

破除迴圈等待

按順序獲取資源,按照account的id的大小進行轉賬的操作,id比較小的賬戶先進行轉賬操作,id比較大的賬戶後進行

轉賬操作。但現實生活中,有些事物是沒有id的,即沒有順序性,這個時候需要強制給其加上順序性。

破除無法剝奪的等待

加入超時,不得已的方法,使用者的此次轉賬操作失敗,使用者的體驗不好

犧牲使用者簡短的等待時間,使用中的方法1

java死鎖例項

在實際程式設計中,要盡量避免出現死鎖的情況,但是讓你故意寫乙個死鎖的程式時似乎也不太簡單,以下是乙個簡單的死鎖例子。package dhp.test1 author 鄧海波 當類的物件flag 1時 t1 先鎖定o1,睡眠500毫秒,然後鎖定o2 而t1在睡眠的時候另乙個flag 0的物件 t2 執...

Java死鎖例項

併發程式設計是指多個執行緒同時進行,對同一資源進行操作,那麼就會產生併發問題。如何解決?可以用鎖。synchronized是最常用的,但是有時難免會出現死鎖的現象。下面就以乙個例項講解死鎖的過程 假定有乙個分布式微博工具,下面是其後台 在她的propagateupdate 方法被呼叫時,exampl...

java製造死鎖

package suo public class deadlocktest implements runnable catch exception e synchronized o2 if flag 1 catch exception e synchronized o1 public static ...