轉:【Java並發編程】之九:死結(含代碼)

來源:互聯網
上載者:User

標籤:current   並發編程   rup   extends   破壞   接下來   對象   csdn   toc   

轉載請註明出處:http://blog.csdn.net/ns_code/article/details/17200937


   當線程需要同時持有多個鎖時,有可能產生死結。考慮如下情形:

      線程A當前持有互斥所鎖lock1,線程B當前持有互斥鎖lock2。接下來,當線程A仍然持有lock1時,它試圖擷取lock2,因為線程B正持有lock2,因此線程A會阻塞等待線程B對lock2的釋放。如果此時線程B在持有lock2的時候,也在試圖擷取lock1,因為線程A正持有lock1,因此線程B會阻塞等待A對lock1的釋放。二者都在等待對方所持有鎖的釋放,而二者卻又都沒釋放自己所持有的鎖,這時二者便會一直阻塞下去。這種情形稱為死結。

      下面給出一個兩個線程間產生死結的樣本,如下:

 

[java] view plain copy
  1. public class Deadlock extends Object {  
  2.     private String objID;  
  3.   
  4.     public Deadlock(String id) {  
  5.         objID = id;  
  6.     }  
  7.   
  8.     public synchronized void checkOther(Deadlock other) {  
  9.         print("entering checkOther()");  
  10.         try { Thread.sleep(2000); }   
  11.         catch ( InterruptedException x ) { }  
  12.         print("in checkOther() - about to " + "invoke ‘other.action()‘");  
  13.   
  14.         //調用other對象的action方法,由於該方法是同步方法,因此會試圖擷取other對象的對象鎖  
  15.         other.action();  
  16.         print("leaving checkOther()");  
  17.     }  
  18.   
  19.     public synchronized void action() {  
  20.         print("entering action()");  
  21.         try { Thread.sleep(500); }   
  22.         catch ( InterruptedException x ) { }  
  23.         print("leaving action()");  
  24.     }  
  25.   
  26.     public void print(String msg) {  
  27.         threadPrint("objID=" + objID + " - " + msg);  
  28.     }  
  29.   
  30.     public static void threadPrint(String msg) {  
  31.         String threadName = Thread.currentThread().getName();  
  32.         System.out.println(threadName + ": " + msg);  
  33.     }  
  34.   
  35.     public static void main(String[] args) {  
  36.         final Deadlock obj1 = new Deadlock("obj1");  
  37.         final Deadlock obj2 = new Deadlock("obj2");  
  38.   
  39.         Runnable runA = new Runnable() {  
  40.                 public void run() {  
  41.                     obj1.checkOther(obj2);  
  42.                 }  
  43.             };  
  44.   
  45.         Thread threadA = new Thread(runA, "threadA");  
  46.         threadA.start();  
  47.   
  48.         try { Thread.sleep(200); }   
  49.         catch ( InterruptedException x ) { }  
  50.   
  51.         Runnable runB = new Runnable() {  
  52.                 public void run() {  
  53.                     obj2.checkOther(obj1);  
  54.                 }  
  55.             };  
  56.   
  57.         Thread threadB = new Thread(runB, "threadB");  
  58.         threadB.start();  
  59.   
  60.         try { Thread.sleep(5000); }   
  61.         catch ( InterruptedException x ) { }  
  62.   
  63.         threadPrint("finished sleeping");  
  64.   
  65.         threadPrint("about to interrupt() threadA");  
  66.         threadA.interrupt();  
  67.   
  68.         try { Thread.sleep(1000); }   
  69.         catch ( InterruptedException x ) { }  
  70.   
  71.         threadPrint("about to interrupt() threadB");  
  72.         threadB.interrupt();  
  73.   
  74.         try { Thread.sleep(1000); }   
  75.         catch ( InterruptedException x ) { }  
  76.   
  77.         threadPrint("did that break the deadlock?");  
  78.     }  
  79. }  


     運行結果如下:


     從結果中可以看出,在執行到other.action()時,由於兩個線程都在試圖擷取對方的鎖,但對方都沒有釋放自己的鎖,因而便產生了死結,在主線程中試圖中斷兩個線程,但都無果。


     大部分代碼並不容易產生死結,死結可能在代碼中隱藏相當長的時間,等待不常見的條件地發生,但即使是很小的機率,一旦發生,便可能造成毀滅性的破壞。避免死結是一件困難的事,遵循以下原則有助於規避死結: 

     1、只在必要的最短時間內持有鎖,考慮使用同步語句塊代替整個同步方法;

     2、盡量編寫不在同一時刻需要持有多個鎖的代碼,如果不可避免,則確保線程持有第二個鎖的時間盡量短暫;

     3、建立和使用一個大鎖來代替若干小鎖,並把這個鎖用於互斥,而不是用作單個對象的對象層級鎖;

轉:【Java並發編程】之九:死結(含代碼)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.