当前位置:首页 > JAVA > 正文内容

Java使用CompletableFuture处理阻塞任务

高老师2个月前 (07-01)JAVA79

我们的项目中有1个场景需要下载图片然后转换为base64传输给第三方,由于下载比较耗时,加上转换base64已经导致文件大小增大,所以执行比较慢,修改为CompletableFuture来处理。

第一种是不关心返回结果的写法:

// 存储所有CompletableFuture的列表
List<CompletableFuture<?>> futures = new ArrayList<>();

// 循环创建请求
for (GicStyleImageRequest gicStyleImageRequest : targetData) {
    futures.add(sendRequest(gicStyleImageRequest));
}

// 直接返回成功
return BaseResponseUtil.baseResponseSuccess(MSG_KEY + "处理成功", targetData);
private CompletableFuture<?> sendRequest(GicStyleImageRequest gicStyleImageRequest) {

    return CompletableFuture.runAsync(() -> {

        // 转换图片
        convertImage(gicStyleImageRequest);

        // 请求参数
        BusinessRequest<GicStyleRequest> request = new BusinessRequest<>();

        // 按品牌获取对应店仓编码
        String depotId = ConfigGicUtil.getDepotId(gicStyleImageRequest.getBrandCode());

        // 设置请求地址
        request.setUrl(GicApiEnums.updateStoreGoodsImage.getApiUrl());

        // 设置请求token
        request.setToken(biz.queryToken(depotId));
        request.setEntMicroSignal(biz.queryEntMicroSignal(depotId));

        // 设置请求Json参数
        request.getMap().put("goodsImageInfo", Collections.singletonList(JsonUtil.toJSONString(gicStyleImageRequest)));

        // 获取请求结果
        String jsonResult = GICRequestUtil.gicPost(request);

        // 解析请求结果
        GicUpdateStoreGoodsSpuImageResponse gicBaseResponse = JsonUtil.parseObject(jsonResult, GicUpdateStoreGoodsSpuImageResponse.class);

        // 是否为空
        if (gicBaseResponse == null || gicBaseResponse.getUpdateStoreGoodsImage_response() == null) {
            log.info("达摩商品图片接口返回响应为空:{}", JSON.toJSONString(request));
            return;
        }

        // 状态码是不是 1
        if (!"1".equals(gicBaseResponse.getUpdateStoreGoodsImage_response().getResult())) {
            // 如果失败
            log.info("达摩商品图片接口返回错误:{}", JSON.toJSONString(gicBaseResponse));
            return;
        }

        // 成功上传
        log.info("达摩商品图片接口调用成功:{}", JSON.toJSONString(gicBaseResponse));
    });
}

第二种是需要返回结果的写法,需要supplyAsync而不是runAsync,改下sendRequest中的runAsync为supplyAsync即可,然后主线程等待任务执行完成,循环每个任务的结果即可

// 等待所有请求完成
CompletableFuture<?> allFutures = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]));
try {
    allFutures.get(); // 等待所有请求完成,但不获取结果
} catch (InterruptedException | ExecutionException e) {
    return BaseResponseUtil.baseResponseFail(MSG_KEY + "处理过程存在失败", e.getMessage(), errorMap, successMap);
}

// 获取每个请求结果
for (CompletableFuture<GicUpdateStoreGoodsSpuImageResponse> future : futures) {
    try {
        GicUpdateStoreGoodsSpuImageResponse gicBaseResponse = future.get();
        // 是否为空
        if (gicBaseResponse == null || gicBaseResponse.getUpdateStoreGoodsImage_response() == null) {
            errorMap.add(GicBaseApiMsg.fail("达摩商品接口返回响应为空", ""));
            continue;
        }

        // 状态码是不是 1
        if (!"1".equals(gicBaseResponse.getUpdateStoreGoodsImage_response().getResult())) {
            // 如果失败
            errorMap.add(GicBaseApiMsg.fail("达摩商品接口返回错误:".concat(gicBaseResponse.getUpdateStoreGoodsImage_response().getCause())
                    , gicBaseResponse.getUpdateStoreGoodsImage_response()));
            continue;
        }
        // 成功数据
        successMap.add(GicBaseApiMsg.succeed(gicBaseResponse.getUpdateStoreGoodsImage_response().getData(), gicBaseResponse));
    } catch (InterruptedException | ExecutionException e) {
        errorMap.add(GicBaseApiMsg.fail("执行请求失败", e.getMessage()));
    }
}

扫描二维码推送至手机访问。

版权声明:本文由高久峰个人博客发布,如需转载请注明出处。

本文链接:https://blog.20230611.cn/post/787.html

分享给朋友:

“Java使用CompletableFuture处理阻塞任务” 的相关文章

java编译编码问题,java编译执行时编码问题

java编译编码问题,java编译执行时编码问题

public class test {     public static void main(String[] args) {     &...

java一个类可以有多个构造方法

java一个类可以有多个构造方法

java一个类可以有多个构造方法,根据传参类型和个数来匹配执行哪个构造方法。public class Member {     public Member(){      ...

java限制1个方法同一时间只能被一个线程访问

java限制1个方法同一时间只能被一个线程访问

java限制1个方法同一时间只能被一个线程访问public synchronized void setOrderPay(){ }加上synchronized 修饰符即可...

java增强型for循环

java增强型for循环

Java5 引入了一种主要用于数组的增强型 for 循环,类似js中的for inpublic class Member {     public static void main(String[]&...

java Character 类,java判断字符是否是一个字母,java判断字符是否是一个数字,java判断字符是否是一个空白,java判断字符是否是小写字母,java判断字符是否是大写字母,java转换字符为大写,java转换字符为小写

java Character 类,java判断字符是否是一个字母,java判断字符是否是一个数字,java判断字符是否是一个空白,java判断字符是否是小写字母,java判断字符是否是大写字母,java转换字符为大写,java转换字符为小写

java判断字符是否是一个字母System.out.println(Character.isLetter('a'));java判断字符是否是一个数字System.out.println(Character.isDigit('0'));java判断字符是否是一个空白Sy...

java String 类 ,java 字符串类,java创建字符串,java获取字符串长度,java连接字符串,java格式化字符串

java String 类 ,java 字符串类,java创建字符串,java获取字符串长度,java连接字符串,java格式化字符串

在java中字符串属于对象,刚开始我就疑惑为什么int char等类型都是小写,结果String是大写,java太反人类,后来才知道String是对象。(1).java创建字符串String text = "net"; String tex...