Java并发编程(六)ExecutorService

文章详细介绍了JavaExecutorService的invokeAny和invokeAll两个方法的用法和特性,包括它们如何处理阻塞和异常,以及超时设置。invokeAny用于获取第一个完成的任务结果,而invokeAll则等待所有任务完成。在异常处理方面,invokeAny可能无法捕获所有异常,而invokeAll则会将所有任务的异常信息返回。示例代码展示了这两种方法的具体行为。
摘要由CSDN通过智能技术生成

ExecutorService

invokeAny() he invokeAll() 具有阻塞特性

invokeAny

invokeAny 的作用是取得第一个完成任务的结果的值。
如果线程中增加 if (!Thread.currentThread().isInterrupted()) 判断,则会中断这些线程。
其他线程如果抛出 InterruptedException() 异常,且有一个线程可以正常运行时,主线程并不能捕获到。如果希望捕获需要主动增加 try-catch。
如果所有线程全部异常了 将返回最后一个异常并输出。
invokeAny 可以设置超时时间,超时后仍未返回结果,主线程则会捕获到超时异常。
如果只有一个线程 即超时 又 异常了 主线程会捕获到两个异常

public class MyExecutorService {

    public static class MyCallableA implements Callable {

        @Override
        public Object call() throws Exception {
            for (int i = 0; i < 10; i++){
                System.out.println("CallableA: " + i);
            }
            System.out.println("CallableA end");
            return "CallableA";
        }

    }

    public static class MyCallableB implements Callable {

        @Override
        public Object call() throws Exception {
            for (int i = 0; i < 20; i++){
                System.out.println("CallableB: " + i);
            }
            System.out.println("CallableB end");
            return "CallableB";
        }

    }

    public static class MyCallableC implements Callable {

        @Override
        public Object call() throws Exception {
            for (int i = 0; i < 30000; i++){
                if (!Thread.currentThread().isInterrupted()) {
                    System.out.println("CallableC: " + i);
                } else {
                    System.out.println("线程已被中断");
                    throw new InterruptedException();
                }
            }
            System.out.println("CallableC end");
            return "CallableC";
        }

    }


    public static void main(String[] args) throws ExecutionException, InterruptedException {
        List list =  new ArrayList<>();
        list.add(new MyCallableA());
        list.add(new MyCallableB());
        ExecutorService executorService = Executors.newCachedThreadPool();
        Object o = executorService.invokeAny(list);
        System.out.println("result: " + o);
    }
}

A线程已经执行结束,但B线程仍在继续执行。
在这里插入图片描述
调整main方法


    public static void main(String[] args) throws ExecutionException, InterruptedException {
        List list =  new ArrayList<>();
        list.add(new MyCallableA());
        list.add(new MyCallableC());
        ExecutorService executorService = Executors.newCachedThreadPool();
        Object o = executorService.invokeAny(list);
        System.out.println("result: " + o);
    }

可以看到MyCallableC终止运行
在这里插入图片描述

invokeAll

invokeAll用来发挥所有任务的执行结果,在所有任务都返回前将会阻塞线程。
如果有线程执行异常了, 则会讲异常作为返回值返回
和invokeAny异常 都可以设置超时时间 超时后主线程捕获到 Timeout异常

public class MyExecutorService {

    public static class MyCallableA implements Callable {

        @Override
        public Object call() throws Exception {
            for (int i = 0; i < 5; i++){
                System.out.println("CallableA: " + i);
            }
            System.out.println("CallableA end");
            return "CallableA";
        }

    }

    public static class MyCallableC implements Callable {

        @Override
        public Object call() throws Exception {
            for (int i = 0; i < 5; i++){
                if (!Thread.currentThread().isInterrupted()) {
                    System.out.println("CallableC: " + i);
                } else {
                    System.out.println("线程已被中断");
                    throw new RuntimeException();
                }
            }
            System.out.println("CallableC end");
            return "CallableC";
        }

    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        List list =  new ArrayList<>();
        list.add(new MyCallableC());
        list.add(new MyCallableA());
        ExecutorService executorService = Executors.newCachedThreadPool();
        List<Future<String>> result = executorService.invokeAll(list);
        for (Future future : result) {
            System.out.println("result: " + future.get());
        }
        System.out.println("main end");
    }
}

在这里插入图片描述
修改MyCallableC class

public static class MyCallableC implements Callable {

        @Override
        public Object call() throws Exception {
            for (int i = 0; i < 5; i++){
                if (!Thread.currentThread().isInterrupted()) {
                    System.out.println("CallableC: " + i);
                } else {
                    System.out.println("线程已被中断");
                    throw new RuntimeException();
                }
            }
            if ( 1==1) {
                System.out.println("CallableC 异常了");
                throw new RuntimeException();
            }
            System.out.println("CallableC end");
            return "CallableC";
        }

    }

可以看到 主线程阻塞住了 这里需要对。main重的 future 增加 tryCatch
在这里插入图片描述

修改main方法 增加 try-catch

public static void main(String[] args) throws ExecutionException, InterruptedException {
        List list =  new ArrayList<>();
        list.add(new MyCallableC());
        list.add(new MyCallableA());
        ExecutorService executorService = Executors.newCachedThreadPool();
        List<Future<String>> result = executorService.invokeAll(list);
        for (Future future : result) {
            try {
                System.out.println("result: " + future.get());
            }catch (ExecutionException e){
                System.out.println(e.getMessage());
                e.printStackTrace();
            }
        }
        System.out.println("main end");
    }

可以看到其他线程的返回值也获取到了
在这里插入图片描述

ExecutorService 中的方法都以便携的方式创建线程池,使用两个主要的方法 invokeAny 获取第一个执行结束的线程的结果 invokeAll 获取所有线程的执行结果

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值