【并发编程】- ExecutorService的方法invokeAny与执行快的任务异常处理

101 阅读1分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第26天,点击查看活动详情

接着上一篇文章 - 【并发编程】-ExecutorService的方法invokeAny与执行慢的任务异常处理

方法InvokeAny()与执行时间短的任务异常

修改运行类执行代码如下:

public class InvokeAnyRun {
    public static void main(String[] args) {
        List list = new ArrayList();
        list.add(new FCallable());
        list.add(new SCallable());
        ExecutorService executorService = Executors.newCachedThreadPool();
        try {
            String result = (String) executorService.invokeAny(list);
            System.out.println("已完成任务的返回值:"+result);
        } catch (InterruptedException e) {
            e.printStackTrace();
            System.out.println("First异常");
        } catch (ExecutionException e) {
            e.printStackTrace();
            System.out.println("Second异常");
        }
    }
}

运行结果如下:

com.ozx.concurrentprogram.executor.service.FCallable 开始时间: 1661135442848

com.ozx.concurrentprogram.executor.service.SCallable 开始时间: 1661135442848

com.ozx.concurrentprogram.executor.service.FCallable 结束时间: 1661135442851

com.ozx.concurrentprogram.executor.service.SCallable线程中断了....

已完成任务的返回值:com.ozx.concurrentprogram.executor.service.FCallable

通过显式try-catch捕获异常了,异常原因:null

java.lang.NullPointerException

​ at com.ozx.concurrentprogram.executor.service.SCallable.call(SCallable.java:22) ​ at com.ozx.concurrentprogram.executor.service.SCallable.call(SCallable.java:10) ​ at java.util.concurrent.FutureTask.runcapture(FutureTask.java:266) ​ at java.util.concurrent.FutureTask.run(FutureTask.java) ​ at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) ​ at java.util.concurrent.FutureTask.runcapture(FutureTask.java:266) ​ at java.util.concurrent.FutureTask.run(FutureTask.java) ​ at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) ​ at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) ​ at java.lang.Thread.run(Thread.java:748)

从运行结果看出第二个线程加入了显式的try-catch语句块可以捕获异常信息,但是抛出去的异常在main()方法中却没有得到捕获,也就是字符串First异常和Second异常没有被输出到控制台,也就是说明子线程出现异常时是不影响main线程的主流程的。

方法invokeAny()与执行快的任务异常

在执行时间短的任务出现异常时,在默认情况下是不在控制台输出异常信息的除非是显式使用try-catch捕获,而等待执行时间长的任务返回的结果值。