2017-07-08 15 views
0

指定されたコードスニペットは、wait()メソッドとnotify()メソッドを使用して3つのスレッドを同期させて順番に番号を出力します。リエントラントロックを使用して3つのスレッドを同期する

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

単語は「再入可能」ではなく「再入可能」であり、これらのロックはすでに再入可能です。あなたが何を求めているのか不明です。 – 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

これは、ReentrantLockのConditionクラスの助けを借りてうまくいくことに同意します。後者の場合、各スレッドが実行中であるために時間がかかるため、条件なしのReentrantLockと比較してパフォーマンスが考慮される限り適切です。その機会を得るためには、しかし、前者の場合、それは待機と通知機能を使用しています。ありがとう – GaurZilla

+0

完全に答えを理解していただきありがとうございます! – Kayaman

関連する問題