Java的ExecutorService
接口定义了一个名为invokeAll
的方法,该方法接收要同时处理的Callable
个对象的集合。但是,invokeAll
方法本身在返回之前等待所有任务完成运行,使其成为阻塞方法。
在我的测试环境中,我不关心这些任务的返回值,我只需要它们同时运行。现在,我知道我可以手动创建新的Thread
或Runnable
对象并自己启动它们,但如果我只是创建一个Runnable
或{{的集合,那将会很好而且干净。 1}}对象并将它们传递给一个方法,该方法开始为我执行它们并立即返回。
有人知道现有的库类有我描述的方法吗?在进行一些研究时我找不到一个。
答案 0 :(得分:5)
我真的很惊讶invokeAll
表现得像这样。 submit
方法不会阻止,因此只需为每个任务调用它:
public static <T> Collection<Future<T>> submitAll(ExecutorService service, Collection<? extends Callable<T>> tasks) {
Collection<Future<T>> futures = new ArrayList<>(tasks.size());
for (Callable<T> task: tasks) {
futures.add(service.submit(task));
}
return futures;
}
答案 1 :(得分:2)
如果您对submit
感兴趣,可以使用Future
。 (这也适用于Callable
)
public static List<Future<?>> submitAll(ExecutorService executor, Collection<? extends Runnable> tasks) {
List<Future<?>> result = new ArrayList<Future<?>>(tasks.size());
for (Runnable task : tasks) {
result.add(executor.submit(task));
}
return result;
}
或execute
如果不是
public static void executeAll(ExecutorService executor, Collection<? extends Runnable> tasks) {
for (Runnable task : tasks) {
executor.execute(task);
}
}
这两种方法只是将任务排队,并且将在未来的某个时刻执行。
答案 2 :(得分:0)
您可以使用ExecutorService.invokeAny()
。你必须等待一个线程完成,但不是全部。或者,由于您已经拥有invokeAll的任务列表,因此您可以对它们进行交互并在每个上面调用ExecutorService.submit
。一些额外的代码,但不多......
for(Callable task : myTaskCollection)
{
myExecutorService.submit(task);
}