当前位置: 首页 > 知识库问答 >
问题:

ExecutorService awaitTermination方法未按预期执行

农飞星
2023-03-14

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

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对象都有一个run方法,该方法进行webservice调用,然后将调用的结果写入数据库,包括调用完成的时间。ComplethisProcess方法只是将整个流程的状态写为complete以及流程完成的时间。

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

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

共有1个答案

麻宜春
2023-03-14

如果您希望等待所有线程返回,那么下面的方法是可以信任的。使您的线程类实现callable接口,而不是runnable(如果是callablerun方法将返回一些值。使它返回ThreadName。

创建一个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

 类似资料:
  • 根据以下文档:http://testng.org/doc/documentation-main.html “如果测试类上有一个方法tearDown(),那么在每个测试方法之前和之后都会调用它”(JUnit 3) 我使用的是JUnit版本:3.8.1 这里的这个是在我的测试之前运行的,但我希望它会在测试之后。它在测试后没有运行: 我可以通过将第一行更改为: 但是,下一个类(下面)的表示法与第一个类完

  • 工具:Win7、Launch4J3.5、简单的Hello world Java控制台应用程序(绑定在JAR文件中) 大家好, 我有一个基本的JAVA控制台应用程序,它不请求任何输入,只是一个打开控制台窗口并显示Hello World文本的简单应用程序。 包装程序清单:C:\launch4j\manifest\uac.exe.manifest(也尝试保留此空白) 其余的都是默认的。

  • 我正在尝试编写一个函数,如果< code > selection _ Match = = ' No Match ' then < code > DNB = score _ difference 0.02 然而,我返回相同的df,没有任何修改 虽然它应该回来 Lorem ipsum dolor sit amet,consecetur adipiscing elit,sed do eiusmod te

  • 问题内容: 以下是我要做什么的快速概述。我想从一个方法调用将记录推送到数据库中的两个不同表。如果有任何失败,我希望一切都回滚。因此,如果失败,我希望将提交的任何内容回滚。 其中的接口是使用mybatis映射到数据库并使用Spring注入设置的。 现在,如果失败,所有内容仍然会推送到数据库。我该如何纠正这种行为? 编辑: 我修改了该类,以更准确地描述我要实现的目标。如果我直接运行,则在出现任何问题时

  • 我能够在iothub消息(从云到设备的消息)上打开一个侦听器,但我无法订阅direct方法。我尝试使用mqtt支持,而不是iothub库 我已经跟踪https://docs.microsoft.com/en-us/azure/iot-hub/iot-hub-devguide-direct-methods#mqtt但一定有一个小细节我还没有设法做到正确 这是我的代码(python)

  • 在我的flatter应用程序中,我试图在异步函数完成后使用whenComplete()方法运行一些代码。问题是whenComplete()方法中的代码甚至在异步函数完成之前就被执行了。 我也尝试过使用then()方法,这也产生了相同的结果。 这是我在其中调用异步函数的init函数: 这是异步函数的函数体: 运行应用程序时的控制台输出为: 因此,在调用异步函数getUserHomes的init()函