使用ExecutorService.invokeAll时,即使发生异常,也可以获得所有响应

时间:2016-08-04 14:12:51

标签: java multithreading executorservice

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

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

是否有办法处理所有响应,无论单个线程是否引发异常?

我的测试代码是

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

    }

2 个答案:

答案 0 :(得分:1)

在循环中捕获异常

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

答案 1 :(得分:1)

其他解决方案:

覆盖ThreadPoolExecutor

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

完成给定Runnable的执行后调用的方法。执行任务的线程调用此方法。如果非null,则Throwable是未被捕获的RuntimeException或Error,导致执行突然终止。

来自oracle文档链接的示例代码:

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