7

2 つのスレッドを生成し、CyclicBarrier クラスを使用してそれらが同期するのを待つコードを書いています。問題は、循環バリアが期待どおりに機能せず、メイン スレッドが個々のスレッドの終了を待機しないことです。私のコードは次のようになります。

 class mythread extends Thread{
   CyclicBarrier barrier;
   public mythread(CyclicBarrier barrier) { 
       this.barrier = barrier;
      }

   public void run(){
            barrier.await();
       } 
 }



class MainClass{
 public void spawnAndWait(){
    CyclicBarrier barrier = new CyclicBarrier(2);
    mythread thread1 = new mythread(barrier).start();
    mythread thread2 = new mythread(barrier).start();
    System.out.println("Should wait till both threads finish executing before printing this");
  }
}

私が間違っていることは何ですか?または、これらのバリア同期メソッドを記述するより良い方法はありますか? 助けてください。

4

4 に答える 4

14

メイン スレッドの実行中に、他の 2 つのスレッドを作成し、互いに待機するように指示します。しかし、メインスレッドがそれらを待機するように何も記述せず、待機しないと不平を言います。試す

CyclicBarrier barrier = new CyclicBarrier(3);
mythread thread1 = new mythread(barrier).start();
mythread thread2 = new mythread(barrier).start();
barrier.await(); // now you wait for two new threads to reach the barrier.
System.out.println("Should wait till both threads finish executing before printing this");

ところで。必要がない限り、Thread クラスを拡張しないでください。Runnable を実装し、実装を Thread オブジェクトに渡します。このような:

class MyRunnable implements Runnable {
    public void run(){
        // code to be done in thread
    }
}

Thread thread1 = new Thread(MyRunnable);
thread1.start();

スレッドの拡張を回避するための編集
の正当化。
経験則として、カップリングはできるだけ少なくします。継承は、クラス間の非常に強力な接続です。Thread のデフォルトの動作の一部を変更する (つまり、いくつかのメソッドをオーバーライドする) 場合、またはクラス Thread の保護フィールドにアクセスする場合は、Thread から継承する必要があります。それが望ましくない場合は、より疎結合を選択します - Runnable を実装し、それをコンストラクターパラメーターとして Thread インスタンスに渡します。

于 2010-03-26T10:58:10.213 に答える
2

Thread.join()メソッドを探しています...

thread1.join();
thread2.join();
System.out.println("Finished");

編集:コメントのために...

また、永遠に待ちたくない場合は、スレッドが終了するまで待機する最大ミリ秒数とナノ秒数を指定することもできます

于 2010-03-26T10:05:23.470 に答える
1

この場合、サイクリック バリアは適切な選択ではありません。ここを使用する必要がありCountDownLatchます。

spawnAndWaitメインメソッドからメソッドを呼び出していると思います。

これが機能しない理由は、CyclicBarrierコンストラクターが 2 つあるためです。事後操作を実行するには、2 つのパラメーターのコンストラクターを使用する必要があります。覚えておくべき最も重要なことは、メイン スレッドはawaitメソッドによって待機しないということです。しかし、実行し続けます。ただし、コンストラクターで指定されたスレッドは、生成されたすべてのスレッドがバリアで (メソッドCyclicBarrierによって) 停止したときにのみ実行されます。await

于 2011-09-20T07:38:23.557 に答える