106

利用するメリットはありますか

java.util.concurrent.CountdownLatch

それ以外の

java.util.concurrent.Semaphore ?

私が知る限り、次のフラグメントはほぼ同等です。

1.セマフォ

final Semaphore sem = new Semaphore(0);
for (int i = 0; i < num_threads; ++ i)
{
  Thread t = new Thread() {
    public void run()
    {
      try
      {
        doStuff();
      }
      finally
      {
        sem.release();
      }
    }
  };
  t.start();
}

sem.acquire(num_threads);

2: カウントダウンラッチ

final CountDownLatch latch = new CountDownLatch(num_threads);
for (int i = 0; i < num_threads; ++ i)
{
  Thread t = new Thread() {
    public void run()
    {
      try
      {
        doStuff();
      }
      finally
      {
        latch.countDown();
      }
    }
  };
  t.start();
}

latch.await();

ただし、#2 の場合はラッチを再利用できず、さらに重要なことに、作成されるスレッドの数を事前に知る必要があります (または、すべてのスレッドが開始されるまで待ってからラッチを作成します)。

では、どのような状況でラッチが望ましいのでしょうか?

4

7 に答える 7

118

CountDownLatchあなたの例の正反対に頻繁に使用されます。await()一般に、countown が 0 に達したときにすべてが同時に開始されるように、多くのスレッドがブロックされます。

final CountDownLatch countdown = new CountDownLatch(1);

for (int i = 0; i < 10; ++ i) {
   Thread racecar = new Thread() {    
      public void run() {
         countdown.await(); //all threads waiting
         System.out.println("Vroom!");
      }
   };
   racecar.start();
}
System.out.println("Go");
countdown.countDown();   //all threads start now!

これを MPI スタイルの「バリア」として使用して、すべてのスレッドが他のスレッドが特定のポイントに追いつくまで待機してから続行することもできます。

final CountDownLatch countdown = new CountDownLatch(num_thread);

for (int i = 0; i < num_thread; ++ i) {
   Thread t= new Thread() {    
      public void run() {
         doSomething();
         countdown.countDown();
         System.out.printf("Waiting on %d other threads.",countdown.getCount());
         countdown.await();     //waits until everyone reaches this point
         finish();
      }
   };
   t.start();
}

つまりCountDownLatch、例で示した方法で安全に使用できます。

于 2008-10-08T19:53:50.693 に答える
72

CountDownLatchcountDown()を使用して、一連のスレッドを開始し、すべてのスレッドが完了するまで (または指定された回数呼び出すまで) 待機します。

セマフォは、リソースを使用している同時スレッドの数を制御するために使用されます。そのリソースは、ファイルのようなものにすることも、実行するスレッドの数を制限することで CPU にすることもできます。セマフォのカウントは、異なるスレッドが and を呼び出すたびに増減する可能性がacquire()ありrelease()ます。

あなたの例では、基本的に Semaphore をカウントUPラッチの一種として使用しています。あなたの意図がすべてのスレッドの終了を待つことであることを考えると、 を使用するCountdownLatchと意図が明確になります。

于 2008-10-08T20:42:58.440 に答える
31

簡単な要約:

  1. SemaphoreCountDownLatch異なる目的を果たします。

  2. Semaphoreリソースへのスレッド アクセスを制御するために使用します。

  3. CountDownLatchすべてのスレッドの完了を待機するために使用します

SemaphoreJavadocs からの定義:

ASemaphoreは一連の許可を維持します。許可acquire()が得られるまで、必要に応じてそれぞれがブロックし、それを受け取ります。それぞれが許可を追加し、ブロックしている取得者を解放する可能性があります。release()

ただし、実際の許可オブジェクトは使用されません。Semaphore利用可能な数のカウントを保持し、それに応じて動作します。

それはどのように機能しますか?

セマフォは、リソースを使用している同時スレッドの数を制御するために使用されます。そのリソースは、共有データ、コードのブロック (クリティカル セクション)、または任意のファイルのようなものにすることができます。

異なるスレッドが and を呼び出すと、 a のカウントがSemaphore上下する可能性があります。ただし、どの時点でも、セマフォ数よりも多くのスレッドを持つことはできません。acquire()release()

Semaphore使用例:

  1. ディスクへの同時アクセスを制限する (競合するディスク シークによりパフォーマンスが低下するため)
  2. スレッド作成制限
  3. JDBC 接続のプーリング / 制限
  4. ネットワーク接続の調整
  5. CPU またはメモリを集中的に使用するタスクのスロットリング

セマフォの使用については、この記事をご覧ください。

CountDownLatchJavadocs からの定義:

1 つ以上のスレッドが、他のスレッドで実行されている一連の操作が完了するまで待機できるようにする同期支援。

それはどのように機能しますか?

CountDownLatchスレッドの数で初期化されたカウンターを持つことによって機能します。これは、スレッドが実行を完了するたびに減少します。カウントがゼロになると、すべてのスレッドが実行を完了し、ラッチを待機しているスレッドが実行を再開したことを意味します。

CountDownLatch使用例:

  1. 最大並列処理の実現: 最大並列処理を実現するために、同時に多数のスレッドを開始したい場合があります。
  2. 実行を開始する前に、N 個のスレッドが完了するのを待ちます
  3. デッドロック検出。

この記事CountDownLatchを見て、概念を明確に理解してください。

この記事のFork Join Poolもご覧ください。といくつかの類似点があります。CountDownLatch

于 2015-11-10T07:12:55.063 に答える
2

自由に入手できるソースを見ると、2 つのクラスの実装にマジックはなく、パフォーマンスはほとんど同じはずです。あなたの意図をより明確にするものを選択してください。

于 2008-10-08T19:31:35.450 に答える
0

CountdownLatchawait()カウントがゼロになるまで、スレッドをメソッドで待機させます。したがって、すべてのスレッドを何かの 3 回の呼び出しまで待機させたい場合は、すべてのスレッドを実行できます。通常、 ALatchはリセットできません。

Semaphore、スレッドがパーミットを取得できるようにします。これにより、多数のスレッドが一度に実行されるのを防ぎ、続行するために必要なパーミットを取得できない場合はブロックされます。Semaphoreパーミットは、待機中の他のスレッドが続行できるように戻すことができます。

于 2008-10-08T19:25:10.157 に答える