如何检查所有任务是否已完成(正常或突然)?

时间:2015-08-31 09:56:08

标签: java multithreading threadpoolexecutor

我有以下课程:

public class Service{
    private static final ExecutorService executor = Executors.newFixedThreadPool(4);

    public synchronized void execute(Collection<Runnable> runs){
        for(Runnable r: runs){
            executor.execute(r);
        }
    }

    public boolean isComplete(){
        //should return true iff all tasks applied by the execute(Collection<Runnable> runs) 
        //method're finished their execution (normally or abruptly, 
        //it doesn matter)
    }
}

如何实施isComplete()方法。我需要检查当前是否有正在进行的任务。如果执行程序被清除(所有任务都已完成),则该方法应返回true,否则返回false。

3 个答案:

答案 0 :(得分:4)

鉴于您使用的是ExecutorService,您可以使用submit代替execute,并将返回的Future存储在列表中。然后在isComplete()内迭代所有Future并在每个isDone()上调用Future。 (如果需要,此方法还允许您通过class Service{ private static final ExecutorService executor = Executors.newFixedThreadPool(4); private List<Future<?>> futures; public void execute(Collection<Runnable> runs){ futures = runs.stream() .map(r -> executor.submit(r)) .collect(Collectors.toList()); } public boolean isComplete(){ for (Future<?> future : futures) if (!future.isDone()) return false; return true; } } )取消提交的任务。

例如

futures

根据您的使用情况,您可以通过从isComplete列表中删除项目来获得更好的效果,但您(可能)需要同步 public synchronized boolean isComplete(){ Iterator<Future<?>> itr = futures.iterator(); while (itr.hasNext()) { if (itr.next().isDone()) itr.remove(); else return false; } return true; } 方法:

execute

在编写此代码示例时,它假定您只对Service的每个实例调用synchronized,因此不需要是execute。如果您在每个Service实例上有多个并发呼叫者futures,请注意,这会在每次调用execute时替换"test AND test2 OR test3 AND test4" 列表。您可以通过仅使用该类一次性或通过附加到期货来处理该问题。这完全取决于您的用例。

答案 1 :(得分:1)

您可以调用shutdown()方法让执行程序终止所有线程并关闭池。然后调用isTerminated(),如果所有线程都被终止,它将返回true。

如果要阻止执行,可以使用awaitTerminationMethod(),最后shutDownNow()将终止池,无论线程是否已完成执行。

答案 2 :(得分:1)

CountDownLatch解决了我的问题。

ExecutorService WORKER_THREAD_POOL 
  = Executors.newFixedThreadPool(10);
CountDownLatch latch = new CountDownLatch(2);
for (int i = 0; i < 2; i++) {
    WORKER_THREAD_POOL.submit(() -> {
        try {
            // ...
            latch.countDown();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    });
}
 
// wait for the latch to be decremented by the two remaining threads
latch.await();