2017-02-06 22 views
0
StopWatch sw = new StopWatch(); 
    sw.start(); 
    ExecutorService executor = Executors.newFixedThreadPool(MYTHREADS); 

    for (int i = 0; i < MYTHREADS; i++) { 
     Runnable worker = new SingleConnectionRunnable(); 
     executor.execute(worker); 
    } 

    sw.stop(); 
    System.out.println("total time"+sw.toString()); 
    sw.reset(); 
    sw.start(); 

    for (int i = 0; i < MYTHREADS; i++) { 
     Runnable worker2 = new PooledConnectionRunnable(); 
     executor.execute(worker2); 
    } 
    executor.shutdown(); 
    executor.awaitTermination(Integer.MAX_VALUE, TimeUnit.SECONDS); 
    while (!executor.isTerminated()) { 

    } 

    sw.stop(); 
    System.out.println("total time"+sw.toString()); 

上記のコードでいくつかのperfテストを実行しようとしています。私は別のRunnableに同じexecutorを使用して時間を測定しようとしています。しかし、それはまったく機能しません。最初の「合計時間」は正しくありません。これはミリ秒単位です。スレッドを終了するスレッドを待つ

最初のループで経過時間を印刷してから、2番目のループを印刷します。エグゼキュータを最初に終了してからエグゼキュータを再起動する方法を確認できない

これを行う正しい方法は何ですか?

+1

[ExecutorService、すべてのタスクが完了するのを待つ方法]の可能な複製(http://stackoverflow.com/questions/3269445/executorservice-how-to-wait-for-all-tasks-to-finish) – AxelH

答えて

1

まず、すべてのタスクが終了するまでawaitTerminationblockになります。潜在的に70 yearsを待ってからwhileループチェックを使用する特別な理由はありますか?

質問に答えるには、最初の実行が完了するのを待つために、CountDownLatchを使用して各スレッドの完了を通知し、完了するまでメインスレッドで待機してください。また、すべてのあなたのスレッドがそうのように、タイミングを開始する前に行く準備が整うまで待つCyclicBarrierを使用することができます。

... 
CountDownLatch latch = new CountDownLatch(MYTHREADS); 
CyclicBarrier cb = new CyclicBarrier(MYTHREADS, new Runnable() { 
    @Override public void run() { 
     sw.start(); 
    } 
}); 

for (...) { 
    Runnable worker = ... 
    executor.execute(new Runnable() { 
     @Override public void run() { 
      try { 
       cb.await(); 
      } catch (Exception e) { 
       throw new RuntimeException(e); 
      } 

      worker.run(); 
      latch.countDown(); 
     } 
    }); 
} 

latch.await(); 
sw.stop(); 
... 

私はセットアップにオブジェクト割り当てのオーバーヘッドを測定避けるために、forループの先頭にsw.start()を移動しました(おそらく、それはミリ秒単位で測定されないでしょう)。

また、2つの並行性クラスを無期限に実行するようにリセットすることもできます。

+1

私が注意しているように、OPがawaitTermination(Long.MAX_VALUE、TimeUnit。)に変更した後、68年以内にexecutorサービスが完了しなければ、 'awaitTermination'が返ってくることがまだ懸念されています。DAYS) 'は、宇宙の終わりまで待つか、言い換えれば、while(!executor.isTerminated()){}'も、25269512429739111年以内のハードウェア障害のために偽りに終了する可能性があります。それに加えて、 'ExecutorService'が' invokeAll'を提供するので、 'CountDownLatch'は過剰であるかもしれません。これは全てのジョブが完了したときに戻るものです。しかし、あなたは 'Callable'を使用しなければなりません... – Holger

+0

@Holger OPがCallableを既に使用していても、' invokeAll'を使う価値はあると思いますが、コードをさらに複雑にするだろうと思った... – xTrollxDudex

0

何が今やっていることは次のとおりです。

  1. あなたがのように仕上げるためにあなたが彼らを待っていないストップウォッチ

を読むストップウオッチ

  • スタートを数のスレッドを起動します2番目のループで


    これはこれを解決するための方法です。

    SingleConnectionRunnableでコールバックメソッドを作成します。

    このメソッドは、この実行時の最後の時点(終了時)に呼び出され、ループを開始するクラスによってキャッチされます(これは問題のメソッドではありませんが問題ありません)。

    このコールバックメソッドでは、呼び出された回数を追跡します。

    MYTHREADと呼ばれるときは、ストップウォッチの時間を印刷します。

    開始されたスレッドがすべて終了するまでにどれくらいかかります。

  • 関連する問題