当前位置: 首页 > 面试题库 >

在Java 7中是invokeAll()的阻塞调用

益光亮
2023-03-14
问题内容
ExecutorService executorService = Executors.newSingleThreadExecutor();

Set<Callable<String>> callables = new HashSet<Callable<String>>();

callables.add(new Callable<String>() {
    public String call() throws Exception {
        return "Task 1";
    }
});
callables.add(new Callable<String>() {
    public String call() throws Exception {
        return "Task 2";
    }
});
callables.add(new Callable<String>() {
    public String call() throws Exception {
        return "Task 3";
    }
});

List<Future<String>> futures = executorService.invokeAll(callables);

for(Future<String> future : futures){
    System.out.println("future.get = " + future.get());
}

对于此代码段。我的问题是“ invokeAll()是否是阻塞调用”?我的意思是,当代码运行到invokeAll()行时,我们是否在此等待所有生成的结果?


问题答案:

执行给定的任务,并在所有任务完成时返回保存其状态和结果的期货列表。 Future.isDone()对于返回列表的每个元素为true。
请注意,已完成的任务可能已正常终止,也可能引发异常。如果在进行此操作时修改了给定的集合,则此方法的结果不确定。

期货只能在执行完成时完成,因此,只有在任务执行完毕后才能返回此方法。

它可以引发InterruptedException的情况也表示阻塞动作。

查看invokeAllin java.util.concurrent.AbstractExecutorService(注释内联)的实现:

public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
    throws InterruptedException {
    if (tasks == null)
        throw new NullPointerException();
    ArrayList<Future<T>> futures = new ArrayList<Future<T>>(tasks.size());
    boolean done = false;
    try {
        for (Callable<T> t : tasks) {
            RunnableFuture<T> f = newTaskFor(t);
            futures.add(f);
            execute(f);
        }
        for (int i = 0, size = futures.size(); i < size; i++) {
            Future<T> f = futures.get(i);
            if (!f.isDone()) {
                try {
                    f.get(); // <== *** BLOCKS HERE ***

                } catch (CancellationException ignore) {
                } catch (ExecutionException ignore) {
                }
            }
        }
        done = true;
        return futures;
    } finally {
        if (!done)
            for (int i = 0, size = futures.size(); i < size; i++)
                futures.get(i).cancel(true);
    }
}

实际上,在这些情况下,当Javadoc-Specese似乎难以破译时,通常应该看一下参考实现。(请注意,一些实现细节不是规范的一部分。)



 类似资料:
  • 我完全混淆了,,。 哪个是阻塞,哪个不是? 我的意思是如果我使用父进程是否等待子进程返回/才继续执行。 如何影响这些调用?

  • 本文向大家介绍node.js回调函数之阻塞调用与非阻塞调用,包括了node.js回调函数之阻塞调用与非阻塞调用的使用技巧和注意事项,需要的朋友参考一下 首先,node.js作为javascript运行平台,它采用了事件驱动和异步编程的方式,通过事件注册和异步函数,开发人员可以提高资源利用率,服务器的性能也能得到改善。其次,对于前端人来说,node.js作为js的运行平台,我们可以通过编写系统级或者

  • 我有一个顶点,它有一个处理程序,可以在事件循环线程中调用Vertx的Web客户端。实际的底层API调用是同步的还是异步的?它会阻塞我的事件循环线程吗?假设我的API调用需要30秒才能返回。 我是否需要用Vertx.execute阻塞(p-

  • 我正在使用Spring Webflux和Spring Boot2,我的场景如下: 在返回之前,我如何将来自流量和正常产品列表的结果连接起来?没有反应控制器是可能的吗? 附言。我不想对从调用1获得的结果调用。block()和CompleteableFuture

  • 我正在使用Spring Webflux和Spring数据jpa,使用PostgreSql作为后端数据库。我不想在进行诸如查找和保存之类的db调用时阻塞主线程。为了实现同样的目标,我在Controller类中有一个主调度器,在服务类中有一个jdbcScheduler。 我定义它们的方式是: 现在,当在我的服务层中进行获取/保存调用时,我这样做: 在控制器中,我执行以下操作: 这是正确的吗?和/或有更

  • 本文向大家介绍Dubbo服务之间的调用是阻塞的吗?相关面试题,主要包含被问及Dubbo服务之间的调用是阻塞的吗?时的应答技巧和注意事项,需要的朋友参考一下 默认是同步等待结果阻塞的,支持异步调用。 Dubbo 是基于 NIO 的非阻塞实现并行调用,客户端不需要启动多线程即可完成并行调用多个远程服务,相对多线程开销较小,异步调用会返回一个 Future 对象。 异步调用流程图如下。