是否存在类似于ExecutorService invokeAll的非阻塞方法?

时间:2013-08-28 16:22:57

标签: java multithreading

Java的ExecutorService接口定义了一个名为invokeAll的方法,该方法接收要同时处理的Callable个对象的集合。但是,invokeAll方法本身在返回之前等待所有任务完成运行,使其成为阻塞方法。

在我的测试环境中,我不关心这些任务的返回值,我只需要它们同时运行。现在,我知道我可以手动创建新的ThreadRunnable对象并自己启动它们,但如果我只是创建一个Runnable或{{的集合,那将会很好而且干净。 1}}对象并将它们传递给一个方法,该方法开始为我执行它们并立即返回。

有人知道现有的库类有我描述的方法吗?在进行一些研究时我找不到一个。

3 个答案:

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