gpt4 book ai didi

java - invokeAll 与 CompletionService

转载 作者:太空宇宙 更新时间:2023-11-04 07:37:35 27 4
gpt4 key购买 nike

我有一个由多个线程访问的类,每个线程请求该类的一个方法。每个方法依次执行多个 Callables。该类使用ExecutorService中的threadPool通过invokeAll((Collection>)executableTasks)方法执行这些Callables。设置如下所示:

public MyClass {
private final ExecutorService threadPool = Runtime.getRuntime().availableProcessors();

public void method1() {
List<SomeObject> results = new ArrayList<>();
List<Callable<Void>> tasks = new ArrayList<Callable<Void>>();
tasks.add(new Callable<Void>(){ ... results.add(someObject);} );
threadPool.invokeAll(tasks);
}

public void method2() {
List<SomeObject> results = new ArrayList<>();
List<Callable<Void>> tasks = new ArrayList<Callable<Void>>();
tasks.add(new Callable<Void>(){ ... results.add(someObject);} );
threadPool.invokeAll(tasks);
}

}

我很困惑这是否会同时执行类中的任务,或者 invokeAll() 会阻止执行直到一个方法中的任务完成(意味着执行将在方法内部并发发生,但不会在类级别发生)?或者我应该使用CompletionService来找出任务对应的结果吗?

最佳答案

ExecutorService#invokeAll同时执行所有任务,但调用本身会阻塞,直到所有任务完成。

例如,假设您有三项任务需要 6 秒、2 秒和 10 秒才能完成。如果要同步执行这些,则至少需要 6 + 2 + 10 = 18 秒。但是,使用 invokeAll(在足够大的线程池上),这可能需要最短的时间,即 10 秒。

这意味着方法 method1()method2() 都是阻塞方法,因为使用了 invokeAll()。当您调用 method1() 时,它将阻塞,直到添加到可调用列表中的所有请求都完成为止。 method2() 也是如此。如果从不同的线程调用这些方法,则两个方法中的任务将同时执行。

如果您希望方法是异步的,您需要为方法内的每个任务单独调用 threadPool.submit(callable) 并将返回的 future 收集在列表中。您可以返回一个列表或使用 CompletionService 来帮助实现此目的,是的。

PS - 您的示例中的这一行不起作用:

ExecutorService threadPool = Runtime.getRuntime().availableProcessors();

我认为你想要这个:

ExecutorService threadPool = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());

希望这有帮助。

关于java - invokeAll 与 CompletionService,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16601038/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com