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

88 阅读1分钟

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

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

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

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(super.getClass().getName()+"  结束时间:  "+System.currentTimeMillis());
        return super.getClass().getName();
    }
}

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

public class SCallable implements Callable<String> {
    @Override
    public String call() throws Exception {
        System.out.println(super.getClass().getName()+" 开始时间: "+System.currentTimeMillis());
        for (int i = 0; i < 2345 ; i++) {
            Math.random();
            Math.random();
            Math.random();
        }
        if(true){
            System.out.println(super.getClass().getName()+"线程中断了....");
            throw new NullPointerException();
        }
        System.out.println(super.getClass().getName()+" 结束时间: "+System.currentTimeMillis());
        return super.getClass().getName();
    }
}

运行类执行代码如下:

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();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }

    }
}

运行结果如下:

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

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

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

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

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

从运行结果看出能获取到第一个线程的返回值,第二个线程中断了,但是抛出的空指针异常却没有在控制台输出。

如果想要在Callable中捕获异常信息,那么需要显式地添加try-catch语句块。

修改第二个线程执行代码如下:

public class SCallable implements Callable<String> {
    @Override
    public String call() throws Exception {
        try{
            System.out.println(super.getClass().getName()+" 开始时间: "+System.currentTimeMillis());
            for (int i = 0; i < 2345 ; i++) {
                Math.random();
                Math.random();
                Math.random();
            }
            if(true){
                System.out.println(super.getClass().getName()+"线程中断了....");
                throw new NullPointerException();
            }
            System.out.println(super.getClass().getName()+" 结束时间: "+System.currentTimeMillis());
        }catch(Exception e){
            e.printStackTrace();
            System.out.println("通过显式try-catch捕获异常了,异常原因:"+e.getMessage());
            throw e;
        }
        return super.getClass().getName();
    }
}