Java ExecutorService等待终止方法未按预期执行

Java ExecutorService等待终止方法未按预期执行,java,concurrency,threadpool,executorservice,Java,Concurrency,Threadpool,Executorservice,我试图用Java编写一个进程,该进程并发执行一系列任务,等待任务完成,然后将整个进程标记为完成。每个任务都有自己的信息,包括单个任务完成的时间。我正在为流程使用ExecutorService,并将流程的本质概括如下: List<Foo> foos = getFoos(); ExecutorService executorService = Executors.newFixedThreadPool(foos.size()); for (Foo foo : foos) { exe

我试图用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();
List foos=getFoos();
ExecutorService ExecutorService=Executors.newFixedThreadPool(foos.size());
for(Foo-Foo:foos){
executorService.execute(新的MyRunnable(foo));
}
executorService.shutdown();
试一试{
执行器服务。等待终止(Long.MAX_值,时间单位。秒);
}捕捉(中断异常e){
//记录错误。
}
completeThisProcess();
每个MyRunnable对象都有一个run方法,该方法进行webservice调用,然后将调用结果写入数据库,包括调用完成的时间。completeThisProcess方法只是将整个流程的状态与流程完成的时间一起写入为complete

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


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

如果要等待所有线程返回,则可以信任以下方法。 使线程类实现
可调用
接口,而不是
可运行
(如果
可调用
运行
方法将返回一些值。使其返回threadName

创建可调用对象的列表,并使用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);
ExecutorService ExecutorService=Executors.newFixedThreadPool(foos.size());
列表任务=新建ArrayList();
for(Foo-Foo:foos){
添加(新的MyCallable(foo));
}
executorService.invokeAll(任务);
如果您想使用它,invokeAll将返回未来对象的列表

您可以使用
倒计时闩锁

CountDownLatch cdl=新的CountDownLatch(foo.size);

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


标题“编写进程”是不可能的在Java中。你在编译字节码,然后由虚拟机解释和执行。他不是指一个文字过程。只是一个做一些事情的应用程序。我甚至不知道如何回应你。我一般使用“过程”这个词。我在写一个算法,是不是更好?请更迂腐一点。@jagerads more caps,anywaYes……我猜你的代码> MyRunnaby类有问题。你对ExctuutOrService的使用看起来很好。如果你确信Runnabl是好的,仍然不能找到问题,我会考虑在ExcutoService之外顺序执行所有这些,看看是否有效。