首页 > 解决方案 > ExecutorService.submit() 与 ExecutorSerivce.invokeXyz()

问题描述

ExecutorService包含以下方法:

我对使用 termssubmitinvoke. 这是否意味着invokeXyz()方法通过底层线程池尽快调用这些任务并对submit()提交的任务进行某种调度。

这个答案说“如果我们想等待所有已提交给 ExecutorService 的任务完成”。这里的“等待”指的是什么?

标签: javamultithreading

解决方案


两者都invoke..()submit()立即执行它们的任务(假设线程可用于运行任务)。不同之处在于invoke...()它将等待在不同线程中运行的任务完成后再返回结果,而submit()将立即返回,这意味着它执行的任务仍在另一个线程中运行。

换句话说,从Future返回的对象invokeAll()保证处于Future.isDone() == true. 从返回的Future对象submit()可以处于Future.isDone() == false.

我们可以很容易地证明时间差异。

public static void main(String... args) throws InterruptedException {
    Callable<String> c1 = () -> { System.out.println("Hello "); return "Hello "; };
    Callable<String> c2 = () -> { System.out.println("World!"); return "World!"; };
    List<Callable<String>> callables = List.of(c1, c2);
    ExecutorService executor = Executors.newSingleThreadExecutor();

    System.out.println("Begin invokeAll...");
    List<Future<String>> allFutures = executor.invokeAll(callables);
    System.out.println("End invokeAll.\n");

    System.out.println("Begin submit...");
    List<Future<String>> submittedFutures = callables.stream().map(executor::submit).collect(toList());
    System.out.println("End submit.");
}

结果是在方法完成之前callables打印他们的 Hello World 消息;但方法完成打印 Hello World 。invokeAll()callablessubmit()

/*
Begin invokeAll...
Hello
World!
End invokeAll.

Begin submit...
End submit.
Hello
World!
*/

您可以在 IDE 中使用此代码,方法是在或中添加一些sleep()时间并观察终端打印出来的情况。这应该使您确信确实在等待某事发生,但没有。c1c2invoke...()submit()


推荐阅读