等待使用Phaser

时间:2017-03-10 15:55:50

标签: java multithreading threadpoolexecutor phaser

我希望仅在提交给线程池的所有任务完成后才从我的executeTasks()方法返回。请注意,我的线程池具有可配置的threadpoolsize并使用SynchronousQueue作为后备队列,因此只有在线程可用时才通过提交任务来安全地进行for循环。所以,我只想等待最后的任务。我正在使用Phaser

我创建了一个有1个注册方的Phaser,即当前线程,我在向线程池提交任务之前向Phaser注册了新的一方,当任务完成时我注销了任务方。当for循环通过提交最终任务完成时,我希望我的arriveAndAwaitAdvance()将等待注册方到达,但它只会发现所有这些方在一段时间后被取消注册然后继续前进并从我的方法返回

我认为这将解决我的问题。如果我错了或者还有其他更好的方法可以告诉我。 Countdownlatch无法提供帮助,因为我的threadpoolsize是可配置的。我知道有一个计数器和显示器可以解决这个问题,但我想要像Phaser这样开箱即用的解决方案。

private void executeTasks(TheadPoolExecutor threadPool, Iterator<String> it) {
    final Phaser phaser = new Phaser(1);

    for (final String id : IteratorUtils.iterable(it)) {
        phaser.register();
        threadPool.execute(() -> {
        // phaser.arrive();
            try {
                thread.sleep(10000 * id.length());
            } finally {
                phaser.arriveAndDeregister();
            }
        });
    }
    phaser.arriveAndAwaitAdvance();
    phaser.arriveAndDeregister();
}

1 个答案:

答案 0 :(得分:0)

我之前从未使用Phaser,但我认为CountDownLatch是处理此任务的更好方法。

CountDownLatch是一个同步更改器,它允许一个或多个线程等待,直到在其他线程中执行的一组操作完成。

使用CountDownLatch时,有两种方法很有用:

  • countDown在任务完成时递减计数器。
  • await用于当前线程(例如main)等待其他线程完成。

*

private void executeTasks(TheadPoolExecutor threadPool, Iterator<String> it) {
    final CountDownLatch countDownLatch = new CountDownLatch(threadPool.getPoolSize());

    for (final String id : IteratorUtils.iterable(it)) {
        threadPool.execute(() -> {
            try {
                thread.sleep(10000 * id.length());
                countDownLatch.countDown();
            } catch (InterruptedException ex) {}
        });
    }
    countDownLatch.await();
  }

这里使用线程池中的线程数初始化CountDownLatch。