使用 ExecutorService.invokeAll 时是否有一种方法可以获取所有响应,即使发生异常也是如此

When using the ExecutorService.invokeAll is there a way of getting all responses even if an exception occurred

在 java 中,我想 运行 多个线程并从所有线程中获取响应。

我遇到的问题是,当我执行 String temp = r.get() 时,如果其中一个线程抛出异常,它就会陷入困境,并且不会给我其余线程的响应。

有没有办法处理所有响应,而不管单个线程是否抛出异常?

我的测试代码是

    ExecutorService es = Executors.newFixedThreadPool(2);
    List<CallTest> callList = new ArrayList<>();

    callList.add(new CallTest(1));
    callList.add(new CallTest(2));
    callList.add(new CallTest(3));
    callList.add(new CallTest(4));


    try {
        List<Future<String>> returns = es.invokeAll(callList);
        for (Future<String> r : returns) {
            String temp = r.get();
            System.out.println("returned " + temp);

        }
    } catch (InterruptedException e) {
        System.out.println("Interrupted Exception catch");
        e.printStackTrace();
    } catch (ExecutionException e) {
        System.out.println("Execution Exception catch");
        e.printStackTrace();

    }

在循环中捕获异常

for (Future<String> r : returns) {
    try {
        String temp = r.get();
        System.out.println("returned " + temp);
    } catch (InterruptedException e) {
        System.out.println("Interrupted Exception catch");
        e.printStackTrace();
    } catch (ExecutionException e) {
        System.out.println("Execution Exception catch");
        e.printStackTrace();
    }
}

其他解决方案:

覆盖 ThreadPoolExecutor

中的 afterExecute 方法
protected void afterExecute(Runnable r,
                Throwable t)

Method invoked upon completion of execution of the given Runnable. This method is invoked by the thread that executed the task. If non-null, the Throwable is the uncaught RuntimeException or Error that caused execution to terminate abruptly.

oracle 文档中的示例代码link:

class ExtendedExecutor extends ThreadPoolExecutor {
   // ...
   protected void afterExecute(Runnable r, Throwable t) {
     super.afterExecute(r, t);
     if (t == null && r instanceof Future<?>) {
       try {
         Object result = ((Future<?>) r).get();
       } catch (CancellationException ce) {
           t = ce;
       } catch (ExecutionException ee) {
           t = ee.getCause();
       } catch (InterruptedException ie) {
           Thread.currentThread().interrupt(); // ignore/reset
       }
     }
     if (t != null)
       System.out.println(t);
   }
 }