执行程序服务等待终止方法未按预期执行



我正在尝试用Java编写一个进程,该进程同时执行一系列任务,等待任务完成,然后将整个过程标记为完成。每个任务都有自己的信息,包括单个任务何时完成。我正在使用执行器服务进行该过程,并将该过程的本质归结如下:

List<Foo> foos = getFoos();
ExecutorService executorService = Executors.newFixedThreadPool(foos.size());
for (Foo foo : foos) {
    executorService.execute(new MyRunnable(foo));
}
executorService.shutdown();
try {
    executorService.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS);
} catch (InterruptedException e) {
    // log the error.
}
completeThisProcess();

每个 MyRunnable 对象都有一个运行方法,该方法进行 Web 服务调用,然后将调用结果写入数据库,包括调用完成的时间。completeThisProcess 方法只是将整个过程的状态与该过程完成的时间一起写入

我遇到的问题是,当我在进程完成后查看数据库时,completeThisProcess 方法显然能够在所有 MyRunnable 完成之前执行。我注意到,从 completeThisProcess 方法写入的时间甚至偶尔会在最后一个 MyRunnable 任务完成之前超过 20-30 秒。

我写的过程有什么明显的问题吗?也许我没有正确理解 ExecutorService,但我认为 awaitTerminate 方法应该确保所有 MyRunnable 实例都已完成其运行方法(当然,假设它们无一例外地完成(,这将导致所有子任务的完成时间早于整个过程的完成时间。

如果你想等待所有线程返回,那么以下方法可以信任。让你的线程类实现Callable接口而不是Runnable(在这种情况下Callable run方法将返回一些值。使其返回线程名称。

创建一个Callable对象列表并使用 invokeAll 方法,该方法将等待所有线程返回。对于下面的代码,假定线程类名为 MyCallable。

ExecutorService executorService = Executors.newFixedThreadPool(foos.size());
List<Callable> tasks = new ArrayList<>();
for (Foo foo : foos) {
  tasks.add(new MyCallable(foo));
 }
 executorService.invokeAll(tasks);

invokeAll 返回未来对象的列表,如果你想使用它。

您可以使用 CountDownLatch .

CountDownLatch cdl = new CountDownLatch(foo.size);

使用cdl.countDown()方法在运行方法中倒计时。在 for 循环之后使用 cdl.await,然后它将等待直到 cdl 变为零。

标题

相关内容

  • 没有找到相关文章

最新更新