有以下**,模擬的是兩個賬戶之間的轉賬情況
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 ...