JAVA并发编程篇--ExecutorCompletionService获取线程执行结果

1 创建合适的线程池:

创建线程池方式参考:https://blog.csdn.net/l123lgx/article/details/105731660

本文创建固定线程个数的线程池:

ExecutorService executorService = Executors.newFixedThreadPool(2);

2 包装ExecutorCompletionService:

   ExecutorCompletionService<Map<String, Object>> completionService = new ExecutorCompletionService<>(executorService);

3 线程执行业务:

 completionService.submit(() -> {
            return methodA();
        });
 completionService.submit(() -> {
            return methodB();
        });
 private static Map<String, Object> methodB() {
        Map<String, Object> mapData = new HashMap<>(3);
        Object data = null;
        /**
         * 业务处理-- 耗时3秒
         * data = xxx;
         */
        // 返回结果
        mapData.put("type", "methodBResult");
        mapData.put("data", data);
        return mapData;
    }

    private static Map<String, Object> methodA() {
        Map<String, Object> mapData = new HashMap<>(3);
        Object data = null;
        /**
         * 业务处理-- 耗时6秒
         * data = xxx;
         */
        // 返回结果
        mapData.put("type", "methodAResult");
        mapData.put("data", data);
        return mapData;
    }

4 阻塞获取执行结果:

	for (int i = 0; i < 2; i++) {
       // 获得结果并处理
        Map<String, Object> oneMapResult = completionService.take().get();
        if ("methodAResult".equalsIgnoreCase(oneMapResult.get("type").toString())) {
            // 方法A 返回的结果
        }
        if ("methodBResult".equalsIgnoreCase(oneMapResult.get("type").toString())) {
            // 方法B 返回的结果
        }
    }

5 完整代码:

package org.lgx.bluegrass.bluegrasscoree.util.testfuture;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @Description TODO
 * @Date 2022/9/28 16:42
 * @Author lgx
 * @Version 1.0
 */
public class CompletionFuture {

    public static void main(String[] args) throws InterruptedException, ExecutionException {
        ExecutorService executorService = Executors.newFixedThreadPool(2);
        ExecutorCompletionService<Map<String, Object>> completionService = new ExecutorCompletionService<>(executorService);
        completionService.submit(() -> {
            return methodA();
        });
        completionService.submit(() -> {
            return methodB();
        });
        for (int i = 0; i < 2; i++) {
            // 获得结果并处理
            Map<String, Object> oneMapResult = completionService.take().get();
            if ("methodAResult".equalsIgnoreCase(oneMapResult.get("type").toString())) {
                // 方法A 返回的结果
            }
            if ("methodBResult".equalsIgnoreCase(oneMapResult.get("type").toString())) {
                // 方法B 返回的结果
            }
        }
         executorService.shutdown();
    }

    private static Map<String, Object> methodB() {
        Map<String, Object> mapData = new HashMap<>(3);
        Object data = null;
        /**
         * 业务处理
         * data = xxx;
         */
        // 返回结果
        mapData.put("type", "methodBResult");
        mapData.put("data", data);
        return mapData;
    }

    private static Map<String, Object> methodA() {
        Map<String, Object> mapData = new HashMap<>(3);
        Object data = null;
        /**
         * 业务处理
         * data = xxx;
         */
        // 返回结果
        mapData.put("type", "methodAResult");
        mapData.put("data", data);
        return mapData;
    }
}

6 与Future获取线程执行结果对比:
(1)ExecutorCompletionService,线程在返回结果后会加入到BlockingQueue队列中,所以其可以优先获取耗时最小的线程结果;Future 在获取线程的结果时只能按顺序获取线程的结果;
(2)ExecutorCompletionService ,由于使用了队列进行了Future的结果存储,所以需要手动的调用 take、poll 方法从队列中剔除Future的结果,以此来减小队列的大小,避免OOM;

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值