【并发编程】- ExecutorService的方法invokeAny与全部任务发生异常处理(二)

67 阅读1分钟

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

方法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("进入捕获到 InterruptedException");
        } catch (ExecutionException e) {
            e.printStackTrace();
            System.out.println("进入捕获到 ExecutionException");
        }
    }
}

运行结果如下:

com.ozx.concurrentprogram.executor.service.FCallable 开始时间: 1661506387907 com.ozx.concurrentprogram.executor.service.SCallable 开始时间: 1661506387907 com.ozx.concurrentprogram.executor.service.FCallable 结束时间: 1661506387911 创建异常 com.ozx.concurrentprogram.executor.service.SCallable线程中断了.... 进入捕获到 ExecutionException java.util.concurrent.ExecutionException: java.lang.Exception: com.ozx.concurrentprogram.executor.service.SCallable线程报错了 at java.util.concurrent.FutureTask.report(FutureTask.java:122) at java.util.concurrent.FutureTask.get(FutureTask.java:192) at java.util.concurrent.AbstractExecutorService.doInvokeAny(AbstractExecutorService.java:193) at java.util.concurrent.AbstractExecutorService.invokeAny(AbstractExecutorService.java:215) at com.ozx.concurrentprogram.executor.controller.InvokeAnyRun.main(InvokeAnyRun.java:28) Caused by: java.lang.Exception: com.ozx.concurrentprogram.executor.service.SCallable线程报错了 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)

从运行结果看出二个线程都出现异常时,返回最后一个异常并且输出。

方法invokeAny(Collection Tasks,timeout,timeUnit)超时设置

方法 T invokeAny(Collection<? extends Callable> tasks,long timeout,TimeUnit timeunit)的作用是在指定时间内取得第一个先执行完的任务的结果值。

第一个线程执行代码如下:

public class FCallable implements Callable<String> {

    @Override
    public String call() throws Exception {
        System.out.println(super.getClass().getName()+"  开始时间:  "+System.currentTimeMillis());
        for (int i = 0; i < 1234 ; i++) {
            Math.random();
            Math.random();
            Math.random();
            System.out.println("FCallable i:"+(i+1));
        }
        System.out.println(super.getClass().getName()+"  结束时间:  "+System.currentTimeMillis());
        return super.getClass().getName();
    }
}