2012-02-08 18 views
3

這其中我試圖證明嵌套鎖問題的代碼,嘗試過使用嵌套鎖,但仍然面臨僵局

import java.util.concurrent.locks.*; 


    class SharedResource{ 
    private static final Lock lock = new ReentrantLock(); 


    private void methodThree(String name,int x) throws Exception{ 
     lock.lock(); 
     while(x <= 15){ 
      System.out.println("METHOD-THREE/THREAD-NAME : "+name+" NUM-VAL "+x); 
      x++; 
      Thread.sleep(250); 
     } 
    } 

    private void methodTwo(String name,int x) throws Exception{ 
     lock.lock(); 
     while(x <= 10){ 
      System.out.println("METHOD-TWO/THREAD-NAME : "+name+" NUM-VAL "+x); 
      x++; 
      Thread.sleep(250); 
     } 
     methodThree(name,x); 
    } 

    public void methodOne(String name,int x) throws Exception{ 
     try{   
      lock.lock(); 
      while(x <= 5){ 
       System.out.println("METHOD-ONE/THREAD-NAME : "+name+" NUM-VAL "+x); 
       x++; 
       Thread.sleep(250); 
      } 
      methodTwo(name,x);   
     }finally{ 
      lock.unlock(); 
     }  
    } 

    } 

    class MyRequestREQ extends Thread{ 

    private SharedResource res; 
    private int num = 1; 

    MyRequestREQ(SharedResource res,String name){ 
     super(name); 
     this.res = res; 
    } 

    @Override 
    public void run(){  
     try{ 
      res.methodOne(Thread.currentThread().getName(),num); 
     }catch(Exception e){ 
      System.out.println(e); 
     } 
    } 
    } 

    public class LockCountPractise{ 
    public static void main(String [] args){ 
     SharedResource resource = new SharedResource(); 
     MyRequestREQ[] requests = new MyRequestREQ[]{ 
      new MyRequestREQ(resource,"JACK"), 
      new MyRequestREQ(resource,"JILL"), 
      new MyRequestREQ(resource,"JASON") 
     }; 

     for(int x=0; x < requests.length;x++){ 
      requests[x].start(); 
     } 
    } 
    } 

但我得到的是所有的一個運行的線程「JACK」的輸出,這個線程打印直到數15,然後掛斷。

上述程序是否面臨死鎖問題?

是否需要解鎖類SharedResource的所有方法中的鎖?

等待建議。

回答

3

你沒有在method3中解鎖,所以當第一個線程完成後,其他人無法繼續,因爲他們無法獲得鎖。

是否需要解鎖所有類的方法 SharedResource?

是因爲每次你打電話lock()時間:

如果當前線程已經保持該鎖,則將保持計數 遞增,並且該方法立即返回。

見: http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/locks/ReentrantLock.html#lock%28%29

的建議:你可以獲取方法1鎖和方法3鬆開。所以會有1鎖1解鎖,你會沒事的。無需3次鎖定 - 解鎖循環。

實際上這取決於你想要什麼樣的行爲:

  • 爲了讓不同的線程獲取計數器之間的鎖(線程1數到5,然後thread3來得快,計數然後線程1繼續),你需要鎖定解鎖的每一個方法。
  • 爲了得到一個線程開始和結束計數沒有任何干擾,你需要1個鎖定解鎖
+0

感謝您的答覆,我可以鎖定解鎖在第一方法本身,從方法2和3中除去所有的鎖,這是一個正確的方法? – 2012-02-08 07:37:45

+0

正確的方法取決於你想要的。正如在我編輯答案1鎖定解鎖使得線程依次計數 – destan 2012-02-08 07:42:00

+0

並且還注意到,當您使用1鎖定解鎖時,對於這種特定情況,在method1或method3中的解鎖將是相同的。 – destan 2012-02-08 07:43:09

0

傑克鎖定鎖定3次,但僅釋放一次。 lock()計數:

鎖()

如果當前線程已持有鎖則將保持計數加一,並且該方法立即返回。

解鎖()

如果當前線程是此鎖定的,則將保持計數遞減支架。如果保持計數現在爲零,則鎖定被釋放。

(JavaDoc的)

相關問題