您好,登錄后才能下訂單哦!
這篇文章主要介紹了Java并發編程預防死鎖過程詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
在java并發編程領域已經有技術大咖總結出了發生死鎖的條件,只有四個條件都發生時才會出現死鎖:
1.互斥,共享資源X和Y只能被一個線程占用
2.占有且等待,線程T1已經取得共享資源X,在等待共享資源Y的時候,不釋放共享資源X
3.不可搶占,其他線程不能強行搶占線程T1占有的資源
4.循環等待,線程T1等待線程T2占有的資源,線程T2等待線程T1占有的資源,就是循環等待
只要能破壞其中一個,就可以成功避免死鎖的發生,因為對于共享資源我們要得就是互斥的效果,所以第一個條件是無法破壞的,所以可以從下面三個條件出手,具體實現方式:
1.對于“占用且等待”這個條件,我們可以一次性申請所有的資源,這樣就不存在等待了
class Allocator{ //通過破壞占有且等待條件避免死鎖現象的發生 private List<Object> als = new ArrayList<>(); //一次申請所有的資源 synchronized boolean apply(Object from, Object to){ if (als.contains(from) || als.contains(to)){ //只要存在一個賬戶被其他的業務鎖定則無法完成轉賬業務 return false; }else { als.add(from); als.add(to); } return true; } //歸還資源 synchronized void free(Object from,Object to){ als.remove(from); als.remove(to); } } class Account { //actr應該為單例 private Allocator actr; private int balance; //轉賬 void transfer(Account target, int amt){ //一次性申請轉出和轉入賬戶,直到成功 while (!actr.apply(this,target)); try{ //鎖定轉出賬戶 synchronized (this){ //鎖定轉入賬戶 synchronized (target){ if (this.balance > amt){ this.balance -= amt; target.balance += amt; } } } }finally { actr.free(this, target); } } }
2.對于“不可搶占”這個條件,占用部分資源的線程進一步申請其他資源時,如果申請不到,可以主動釋放它所占有的資源,這樣不可搶占這個條件就破壞掉了
3.對于“循環等待”這個條件,可以靠按序申請資源來預防,所謂按序申請,是指資源是有線性順序的,申請的時候可以先申請資源序號小的,再申請資源序號大的,這樣線性化后自然就不存在循環了
class Accounts{ private int id; private int balance; //轉賬 void transfer(Accounts target,int amt){ Accounts left = this; Accounts right = target; if (this.id > target.id){ left = target; right = this; } //鎖定序號小的賬戶 synchronized (left){ //鎖定序號大的賬戶 synchronized (right){ if (this.balance > amt){ this.balance -= amt; target.balance += amt; } } } } }
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持億速云。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。