2017-12-01 4 views
-2

CountDownLatchが1に設定され、すべてのスレッドで減少すると、3つのスレッドが実行できる理由はWorker.run()です。世界でシンプリーCountDownLatchが動作しない

public class App { 
    public static void main(String[] args){ 

     CountDownLatch latch = new CountDownLatch(1); 

     Thread t1 = new Thread(new Worker(1, latch)); 
     Thread t2 = new Thread(new Worker(2, latch)); 
     Thread t3 = new Thread(new Worker(3, latch)); 

     t1.start(); 
     t2.start(); 
     t3.start(); 

     try { 
      t1.join(); 
      t2.join(); 
      t3.join(); 
      latch.await(); 
     } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

     System.out.println("end"); 

    } 

} 

import java.util.concurrent.CountDownLatch; 

public class Worker implements Runnable { 

    int x; 
    CountDownLatch latch; 

    public Worker(int x, CountDownLatch latch) { 
     this.x = x; 
     this.latch = latch; 
    } 

    @Override 
    public void run() { 

     latch.countDown(); 

     try { 
      for (int i = 0; i < 3; i++) { 
       System.out.println(x); 
       Thread.sleep(1000); 
      } 
     } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

    } 

} 

答えて

2

CountDownLatchを正しく使用していないためです。 javadocから

カウントダウン() は、カウントがゼロに達すると待機中のスレッドをすべて解放、ラッチのカウントをデクリメントします。

あなたは間違った方法を使用しています。これらのスレッドをブロックする場合は、await()を使用する必要があります。その方法は、ラッチのの同期に使用する必要があります。カウントダウン...カウントダウン。

つまり、ラッチをカウントダウンしようとするスレッドが3つあります。 await()への1回の呼び出しは、の後にが発生します。その意味では、このクラスがあなたに与えるAPIを研究してから、あなたの例を再利用して「役に立つ」ことをしてください。

0

@GhostCatあなたの問題の技術的側面を教えてください。あなたがまだ待っていれば、何も同期されません。質問はあなたがやろうとしていることです。あなたは労働者を実行するコードを記述しようとする方法を一つずつ実行して、あなたはこのように同じロックにrunメソッド内のコードを同期させる必要があります(またはオユは1つの許可でセマフォを使用することができます):あなたが唯一のカウントダウンを交換する場合

Object lock = new Object(); 
Thread t1 = new Thread(new Worker(1, object)); 

public class Worker implements Runnable { 

    int x; 
    Object lock; 

    public Worker(int x, Object lock) { 
     this.x = x; 
     this.lock = lock; 
    } 

    @Override 
    public void run() { 

     synchronized(lock){ 
      enter code here 
     } 

    } 

} 

待っていると反対に、あなたは前の変更と同じ結果を得るでしょう。

関連する問題