2017-03-10 52 views
0

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

我创建了一个Phaser,其中包含1个注册方,即当前线程,并且我在向线程池提交任务之前向Phaser注册新方,当任务完成时,我注销任务方。当通过提交最终任务完成循环时,我希望我的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(); 
} 
+0

'invokeAll()'不适合你吗? – Calculator

+0

不,我不想排队等待被调用的任务 – theeminence

+0

我实现了这个,并且这个工作。如果有人发现任何漏洞或更好的方式,请让我知道。 – theeminence

回答

0

我从来没有使用之前Phaser但我认为一个CountDownLatch是更好的办法来处理这个任务。

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

  • countDown是递减计数器当任务完成:

    2种方法使用CountDownLatch时是有用的。

  • await用于当前线程(例如主)等待其他线程完成。

*

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与线程池的线程数。

+0

哦,我很抱歉。我应该提到我的线程池大小是可配置的,countdownlatch不会帮助我 – theeminence

+0

这并不重要,因为您将threadPool作为参数传递。它只需要获取池大小的线程数 – Dimitri

+0

如果我想增加池大小,该怎么办?我不能增加倒计时锁存 – theeminence