等待游泳池完成线程

时间:2017-02-06 13:31:15

标签: java multithreading executorservice

    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());

我正在尝试对上面的代码运行一些性能测试。我尝试在不同的executor上使用相同的Runnable并测量时间。但它不太有效。第一个“总时间”不正确,以毫秒为单位。

我想在第一个循环上打印经过的时间,然后打印第二个循环。不确定我如何等待执行程序完成第一个然后重新启动执行程序。

完成这项工作的正确方法是什么?

2 个答案:

答案 0 :(得分: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();
...

我将sw.start()移动到for循环的开头,以避免测量设置的对象分配开销(可能无论如何都不会被测量,因为它以ms为单位)。

您还可以重置两个并发类以无限次地运行。

答案 1 :(得分:0)

您现在正在做的是:

  1. 启动秒表
  2. 开始几个主题
  3. 阅读秒表
  4. 你不是在等待他们完成第二次循环。

    这是你可以做的解决这个问题的方法。

    在SingleConnectionRunnable中创建一个回调方法。

    此方法将在此runnable的最后一个点(当你终止它时)被调用并被启动循环的类捕获(这不是问题中的方法,但没关系)。

    在此回调方法中,您可以跟踪它的调用次数。

    当打印秒表时间被称为MYTHREAD次数时。

    现在您知道在所有已启动的线程完成之前需要多长时间。