CompletionService 处理异步任务

案例:

public static void main(String[] args) throws Exception {
        ExecutorService executorService = Executors.newCachedThreadPool();
        ArrayList<Future<Integer>> list = new ArrayList<>();
        Future<Integer> future_15 = executorService.submit(() -> {
            TimeUnit.SECONDS.sleep(15);
            System.out.println("执行时长为15s的执行完成。");
            return 15;
        });
        list.add(future_15);

        Future<Integer> future_5 = executorService.submit(() -> {
            TimeUnit.SECONDS.sleep(5);
            System.out.println("执行时长为5s的执行完成。");
            return 5;
        });
        list.add(future_5);

        Future<Integer> future_10 = executorService.submit(() -> {
            TimeUnit.SECONDS.sleep(10);
            System.out.println("执行时长为10s的执行完成。");
            return 10;
        });
        list.add(future_10);

        System.out.println("开始准备获取结果");
        for (Future<Integer> future : list) {
            System.out.println("future.get() = " + future.get());
        }
        Thread.currentThread().join();
    }

上述代码输出结果:

可以看到 耗时最长的最先获取结果,让耗时短的线程等着耗时长的线程

修改 使用【ExecutorCompletionService】提交任务:

public static void main(String[] args) throws InterruptedException, ExecutionException {
        ExecutorService executorService = Executors.newCachedThreadPool();

        ExecutorCompletionService<Integer> completionService =
                new ExecutorCompletionService<>(executorService);

        completionService.submit(() -> {
            TimeUnit.SECONDS.sleep(15);
            System.out.println("执行时长为【15】的执行完成。");
            return 15;
        });
        completionService.submit(() -> {
            TimeUnit.SECONDS.sleep(5);
            System.out.println("执行时长为【5】的执行完成。");
            return 5;
        });
        completionService.submit(() -> {
            TimeUnit.SECONDS.sleep(10);
            System.out.println("执行时长为【10】的执行完成。");
            return 10;
        });

        System.out.println("开始准备获取结果");
        //循环3次是因为上面提交了3个异步任务
        for (int i = 0; i < 3; i++) {
            Integer returnStr = completionService.take().get();
            System.out.println("future.get() = " + returnStr);
        }
        Thread.currentThread().join();
    }

运行结果:

 

可以看出最先执行结束的线程,最先获取结果。

注意:当任务不需要返回值使不要使用 ExecutorCompletionService 来提交任务,因为ExecutorCompletionService 里有一个队列,当不关心返回值时,不会处理这个队列,这个队列就会越积越多,造成OOM(内存溢出)的情况

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值