Java invokeAll vs CompletionService

Java invokeAll vs CompletionService,java,concurrency,Java,Concurrency,我有一个被多个线程访问的类,每个线程请求这个类的一个方法。每个方法依次执行可调用的数量。此类使用ExecutorService中的threadPool通过invokeAll((Collection>)executableTasks)方法执行这些可调用项。 设置如下所示: public MyClass { private final ExecutorService threadPool = Runtime.getRuntime().availableProcessors(); public vo

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

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);
}

}
公共MyClass{
私有最终执行器服务线程池=Runtime.getRuntime().AvailableProcessor();
公共无效方法1(){
列表结果=新建ArrayList();
列表任务=新建ArrayList();
tasks.add(newcallable(){…results.add(someObject);});
threadPool.invokeAll(任务);
}
公开作废方法2(){
列表结果=新建ArrayList();
列表任务=新建ArrayList();
tasks.add(newcallable(){…results.add(someObject);});
threadPool.invokeAll(任务);
}
}

我不知道这是并发执行类中的任务,还是invokeAll()将阻止执行,直到一个方法中的任务完成(意味着执行将在方法内部并发执行,但不是在类级别)?或者我应该使用CompletionService来查找任务的相应结果

根据Java规范
invokeAll
独立地并发执行所有任务。重复调用
invokeAll
也会执行相同的操作,即调用
invokeAll
不会阻止任务的执行


访问:

根据Java规范
invokeAll
独立地并发执行所有任务。重复调用
invokeAll
也会执行相同的操作,即调用
invokeAll
不会阻止任务的执行


访问:

对我来说,这将同时执行类中的任务
invokeAll()
等待直到其所有任务完成,但这是针对当前线程的,当此线程正在等待时,其他线程可以并发执行其任务。对我来说,这将并发执行类中的任务
invokeAll()
等待直到其所有任务完成,但对于当前线程而言,这是一种等待,当此线程正在等待时,其他线程可以并发执行其任务

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

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

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

如果希望这些方法是异步的,则需要为方法中的每个任务分别调用threadPool.submit(可调用),并在列表中收集返回的未来。您可以返回一个列表,也可以使用CompletionService对此提供帮助,是的

PS-示例中的这一行行不通:

ExecutorService threadPool = Runtime.getRuntime().availableProcessors();
我想你想要这个:

ExecutorService threadPool = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
希望这有帮助。

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

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

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

如果希望这些方法是异步的,则需要为方法中的每个任务分别调用threadPool.submit(可调用),并在列表中收集返回的未来。您可以返回一个列表,也可以使用CompletionService对此提供帮助,是的

PS-示例中的这一行行不通:

ExecutorService threadPool = Runtime.getRuntime().availableProcessors();
我想你想要这个:

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

希望这能有所帮助。

它说:执行给定的任务,在所有任务完成时返回一个保留其状态和结果的未来列表。它说:执行给定的任务,在所有任务完成时返回保留其状态和结果的未来列表。“因此,是的,执行将在特定方法中同时发生,但不会在类级别上。”:但是这两个方法是在两个不同的线程中调用的,那么为什么这些任务(来自method1和method2)不会同时执行呢?哎呀,我想他们应该读第一句话。我已经确定了我的答案。谢谢你的提示@Cody同意这两种建议:方法在线程池定义中被阻塞和输入错误。“因此,是的,执行将在特定方法中同时发生,但不会在类级别发生”:但是这两个方法在两个不同的线程中被调用,那么为什么这些任务(来自method1和method2)不会同时执行呢,我想他应该读第一句话。我已经确定了我的答案。谢谢你的提示@Cody同意这两个建议:方法在线程池定义中被阻塞和键入。是的,执行也支持这一点。有人评论说“invokeAll等待所有任务完成”,我对此感到困惑。是的,执行也支持这一点。有人评论说“invokeAll等待所有任务完成”,我对此感到困惑。