Java死鎖的例子

死鎖 

  死鎖是這樣一種情形:多個線程同時被阻塞,它們中的一個或者所有都在等待某個資源被釋放。因爲線程被無限期地阻塞,所以程序不可能正常終止。 

  致使死鎖的根源在於不適當地運用「synchronized」關鍵詞來管理線程對特定對象的訪問。「synchronized」關鍵詞的做用是,確保在某個時刻只有一個線程被容許執行特定的代碼塊,所以,被容許執行的線程首先必須擁有對變量或對象的排他性的訪問權。當線程訪問對象時,線程會給對象加鎖,而這個鎖致使其它也想訪問同一對象的線程被阻塞,直至第一個線程釋放它加在對象上的鎖。 

  因爲這個緣由,在使用「synchronized」關鍵詞時,很容易出現兩個線程互相等待對方作出某個動做的情形。代碼一是一個致使死鎖的簡單例子。 

//代碼一 多線程

 1 class Deadlocker {
 2  int field_1;
 3  private Object lock_1 = new int[1];
 4  int field_2;
 5  private Object lock_2 = new int[1];
 6 
 7  public void method1(int value) {
 8synchronized」 (lock_1) {
 9synchronized」 (lock_2) {
10     field_1 = 0; field_2 = 0;
11    }
12   }
13  }
14 
15  public void method2(int value) {
16synchronized」 (lock_2) {
17synchronized」 (lock_1) {
18     field_1 = 0; field_2 = 0;
19    }
20   }
21  }
22 }
23  

 參考代碼一,考慮下面的過程: 

  ◆ 一個線程(ThreadA)調用method1()。 

  ◆ ThreadA在lock_1上同步,但容許被搶先執行。 

  ◆ 另外一個線程(ThreadB)開始執行。 

  ◆ ThreadB調用method2()。 

  ◆ ThreadB得到lock_2,繼續執行,企圖得到lock_1。但ThreadB不能得到lock_1,由於ThreadA佔有lock_1。 

  ◆ 如今,ThreadB阻塞,由於它在等待ThreadA釋放lock_1。 

  ◆ 如今輪到ThreadA繼續執行。ThreadA試圖得到lock_2,但不能成功,由於lock_2已經被ThreadB佔有了。 

  ◆ ThreadA和ThreadB都被阻塞,程序死鎖。 

  固然,大多數的死鎖不會這麼顯而易見,須要仔細分析代碼才能看出,對於規模較大的多線程程序來講尤爲如此。好的線程分析工具,例如JProbe Threadalyzer可以分析死鎖並指出產生問題的代碼位置。 工具

相關文章
相關標籤/搜索