2017-07-08 34 views
0

下面指定的代碼片段使用wait()和notify()方法同步三個線程來依次打印數字。使用可重入鎖同步三個線程

class JoinTask { 

    private int currentRank = 1; 

    public void doJob(int rank, int printNo) { 
     synchronized (this) { 
      while (rank != currentRank) { 
       try { 
        System.out.println("going to wait by thread:" + printNo); 
        wait(); 
       } catch (InterruptedException ex) { 
        ex.printStackTrace(); 
       } 
      } 
      System.out.println("Job:" + printNo + " : " + currentRank); 
      currentRank++; 
      notifyAll(); 
     } 
    } 
} 

public class ThreeThreadsPlay { 

    public static void main(String[] args) { 
     final JoinTask task = new JoinTask(); 

     Thread A = new Thread() { 
      public void run() { 
       int k = 1; 
       for (int i = 1; i < 30; i++) { 
        task.doJob(k, 1); 
        k = k + 3; 
       }}}; 

     Thread B = new Thread() { 
      public void run() { 
       int k = 2; 
       for (int i = 1; i < 30; i++) { 
        task.doJob(k, 2); 
        k = k + 3; 
       }}}; 

     Thread C = new Thread() { 
      public void run() { 
       int k = 3; 
       for (int i = 1; i < 30; i++) { 
        task.doJob(k, 3); 
        k = k + 3; 
       }}}; 
     C.start(); 
     B.start(); 
     A.start(); 
    }} 

結果:

going to wait by thread:3 
Job:1 : 1 
going to wait by thread:1 
Job:2 : 2 
going to wait by thread:2 
going to wait by thread:1 
Job:3 : 3 
going to wait by thread:3 
Job:1 : 4 
going to wait by thread:1 
Job:2 : 5 
going to wait by thread:2 
going to wait by thread:1 
Job:3 : 6 
going to wait by thread:3 
Job:1 : 7 
going to wait by thread:1 
Job:2 : 8 
going to wait by thread:2 
going to wait by thread:1 
Job:3 : 9 ...and so on 

我怎樣才能達到同樣的使用重入鎖?

使用可重入鎖定來提供這種機制的任何其他示例也將有所幫助。

+1

努力工作。 'ReentrantLock'和'Condition'與'synchronized'和'wait/notify'沒有多大區別。 – Kayaman

+0

我試過了..但它失敗了。因此,我張貼了一些輸入。不要僅僅發表一些聲明,而應該非常感謝一些幫助。 – GaurZilla

+0

這個詞是'折返',而不是'reenterant',並且這些鎖已經是可重入的。不清楚你在問什麼。 – EJP

回答

1

下面是與ReentrantLock/Conditional適當的實施。請小心注意這與你所嘗試的不同之處。鎖的獲取和釋放實際上應該在try-finally塊中處理,以避免無限期地鎖定鎖,但您可以在其他問題中找到這些鎖的示例。

class JoinTask { 

    private int currentRank = 1; 
    final ReentrantLock l = new ReentrantLock(); 
    final Condition c = l.newCondition(); 

    public void doJob(int rank, int threadNumber) { 
     l.lock(); 
     while(rank != currentRank) { 
      c.await(); 
     } 
     System.out.println("Job:" + threadNumber + " : " + currentRank); 
     currentRank++; 
     c.signalAll(); 
     l.unlock(); 
    } 
} 
+1

我同意這可以在Condition類與ReentrantLock的幫助下正常工作,並且只要性能被認爲與沒有條件的ReentrantLock相比就是合適的,因爲在後一種情況下,每個線程都將繼續運行爲了獲得它的機會,但是在前一種情況下,它使用了等待和通知功能。謝謝 – GaurZilla

+0

謝謝你理解答案! – Kayaman