我将如何知道,ExecutorService中的所有线程都已完成执行

时间:2015-07-27 10:07:09

标签: java multithreading

我创建了 ExecutorService ,如:

private static final java.util.concurrent.ExecutorService EXECUTOR_SERVICE = new java.util.concurrent.ThreadPoolExecutor(
        10, // core thread pool size
        5, // maximum thread pool size
        1, // time to wait before resizing pool
        java.util.concurrent.TimeUnit.MINUTES, 
        new java.util.concurrent.ArrayBlockingQueue<Runnable>(MAX_THREADS, true),
        new java.util.concurrent.ThreadPoolExecutor.CallerRunsPolicy());

并使用以下代码添加线程:

EXECUTOR_SERVICE.submit(thread);

现在我想知道EXECUTOR_SERVICE中的所有线程何时完成了他们的任务,以便我可以做一些相关的任务。

请建议任何方法来实现它。

4 个答案:

答案 0 :(得分:2)

您可以使用:

try  {
  executor.awaitTermination(1, TimeUnit.SECONDS);
} catch (InterruptedException e) {
  // Report the interruptedException
}

答案 1 :(得分:2)

使用CountDownLatch。我以前使用过这个并取得了巨大的成功。

  

允许一个或多个线程等待直到在其他线程中执行的一组操作完成的同步辅助。

Javadoc链接有一个很好的例子。

答案 2 :(得分:1)

根据Java Doc提交方法签名是header("Content-type: text/html; charset=utf-8"); require_once '../sdk.class.php'; $cw = new AmazonCloudWatch(); $response = $cw->get_metric_statistics( 'System/Linux', 'MemoryUtilization', date("c", strtotime('-5 minute')), date("c", strtotime('now')), 300, 'Average', 'Percent', array('Name'=> 'InstanceId', 'Value'=>'i-8c15b124') );

提交值返回任务以执行并返回表示任务的挂起结果的Future。 Future的get方法将在成功完成后返回任务的结果。 如果您想立即阻止等待任务,可以使用结构形式为result = exec.submit(aCallable).get();

注意:Executors类包含一组方法,可以转换一些其他常见的类似闭包的对象,例如,PrivilegedAction到Callable表单,以便可以提交它们。

返回

表示未完成任务的未来

答案 3 :(得分:0)

在不修改提交的任务的情况下,您可以查询ThreadPoolExecutor的内部状态,子类ThreadPoolExecutor根据您的要求跟踪任务完成情况,或者从任务提交中收集所有返回的Future并等待他们各自轮流,直到他们都完成。

没有特别的顺序:

选项1:查询ThreadPoolExecutor的状态:

如果您将引用键入ThreadPoolExecutor.getActiveCount()而不是ThreadPoolExecutor,则可以使用ExecutorService

来自ThreadPoolExecutor来源:

/**
 * Returns the approximate number of threads that are actively executing tasks.
 * Returns:
 *   the number of threads
 **/

public int getActiveCount() {
    final ReentrantLock mainLock = this.mainLock;
    mainLock.lock();
    try {
        int n = 0;
        for (Worker w : workers)
            if (w.isLocked())
                ++n;
        return n;
    } finally {
        mainLock.unlock();
    }
}

那里提到“近似”的JavaDoc应该关注你,但是,由于给定的并发执行,它不一定保证是准确的。但是看一下代码,它会锁定并且假设在添加所有任务之前没有在另一个线程中查询,它似乎足以测试任务的完整性。

这里的一个缺点是你要在检查/睡眠循环中连续监视值。

选项2:子类ThreadPoolExecutor:

另一个解决方案(或者可能是补充解决方案)是子类ThreadPoolExecutor并覆盖afterExecute方法,以便跟踪已完成的执行并采取适当的措施。您可以设计子类,以便在X任务完成后调用回调,或者剩余任务的数量减少到0(由于这可能在添加所有任务之前触发,因此存在一些并发问题)等。

选项3:收集任务期货(可能是最佳选择):

每次提交ExecutorService都会返回一个Future,可以在列表中收集。然后循环可以运行并依次等待每个未来,直到所有任务完成。

E.g。

List<Future> futures = new ArrayList<Future>();
futures.add(executorService.submit(myTask1));
futures.add(executorService.submit(myTask2));

for (Future future : futures) {
    // TODO time limit, exception handling, etc etc.
    future.get();
}