我有一系列使用同一线程池完成的不同“任务”.我想衡量执行每个任务所花费的时间,但是为此,我需要等待“任务”中的每个任务(很抱歉,歧义)完成.
当只有一项任务时,我通常会这样做:
ExecutorService e = Executors.newCachedThreadPool();
for (int i=0; i<100; ++i)
e.submit(target);
e.shutdown();
while (!e.isTerminated());
但是由于将有多个任务提交到池中,所以我不能拒绝它.与等待任务完成有关的所有方法都提到“关闭请求后”.好吧,如果我不想关闭它,而是等待所有线程完成然后提交更多任务,该怎么办?
这就是我想做的:
ExecutorService e = Executors.newCachedThreadPool();
for (int i=0; i<100; ++i)
e.submit(target);
// wait for all targets to finish
for (int i=0; i<100; ++i)
e.submit(target); // submit different tasks
// wait... and so on
我考虑过关闭池,然后使用prestartAllCoreThreads再次“唤醒”它,但是后来我意识到这不是ExecutorService方法,而是ThreadPoolExecutor方法.这可以解决吗?关闭它,等待,然后再次激活池?在我看来有点难看.
我还认为最自然的事情是使用CyclicBarrier,但这似乎也是一种特定的方式,而我认为能够将任何ExecutorService用于我正在尝试的工作是最合逻辑的事情去做.
有什么办法可以让我坚持使用ExecutorServices并等待所有任务完成吗?
解决方法:
使用CyclicBarrier完成您需要的工作,如下所示:
// the optionalRunnable can collect the data gathered by the tasks
CyclicBarrier b = new CyclicBarrier(numberOfTasks,optionalRunnable)
Task yourTaks = new Task(...., b);
// inside the run method call b.await() after the work is done;
executor.submit(yourTaks);
(可选)您还可以在主线程中调用await并实例化numTasks 1的屏障.这样,您可以确保仅在执行程序处理完当前批处理后才将其重新提交给执行程序