1、前置

我现在有这么个要求, 调用外部的一个接口, 需要调用5次, 并且拿到5次请求返回数据, 分析结果
JDK:1.8

2、实现代码
@RequestMapping(value = "/createOrder", method = RequestMethod.GET)
@ResponseBody
public CommonResult createOrder(
        @RequestParam(value = "code", required = true) String code
) throws InterruptedException {
    Thread.sleep(2000);
    int i = Integer.parseInt(code) % 2;
    if (i == 0) {
        return CommonResult.success("SUCCESS", code);
    }
    return CommonResult.failMessage(500, "FAIL", code);
}
import com.alibaba.fastjson.JSONObject;
import com.chaim.common.utils.http.HttpUtils;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.function.BiConsumer;

/**
 * @author Chaim
 * @date 2021/8/23 23:16
 */
@Slf4j
public class TestHttpUtil {

    public static void main(String[] args) {
//        for (int i = 0; i < 40; i++) {
//            asynchronousRequest();
//        }
//        asynchronousRequest();
        syncRequest();
    }

    /**
     * 异步执行
     */
    public static void asynchronousRequest() {
        long starTime = System.currentTimeMillis();

        List<CompletableFuture> comlist = new ArrayList<>();
        final List<String> stringListSuccess = new CopyOnWriteArrayList<>();
        final List<String> stringListFail = new CopyOnWriteArrayList<>();

        for (int i = 0; i < 5; i++) {
            int finalI = i;
            // CompletableFuture.supplyAsync: 返回一个新的CompletableFuture,由给定执行器中运行的任务异步完成,并通过调用给定的供应商获得的值。
            CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
                // 执行具体逻辑 
                try {
                    return HttpUtils.sendGet("http://127.0.0.1:8080/tomorrow/paypal/createOrder", "code=" + finalI);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return "";
            // .whenCompleteAsync: 返回一个与此阶段相同结果或异常的新CompletionStage,当此阶段完成时,执行给定操作将使用此阶段的默认异步执行工具执行给定操作,结果(或 null如果没有))和异常(或 null如果没有)这个阶段作为参数。
            }).whenCompleteAsync(new BiConsumer<String, Throwable>() {
                @Override
                public void accept(String s, Throwable throwable) {
                    JSONObject requestParams = JSONObject.parseObject(s);
                    if ("200".equals(requestParams.getString("code"))) {
                        stringListSuccess.add(requestParams.getString("data"));
                    } else {
                        stringListFail.add(requestParams.getString("data"));
                    }
                }
            });
            comlist.add(future);
        }
        // allOf: 返回一个新的CompletableFuture,当所有给定的CompletableFutures完成时,完成。
        CompletableFuture<Void> all = CompletableFuture.allOf(comlist.toArray(new CompletableFuture[5]));

        // 完成后返回结果值,如果完成异常,则返回(未检查)异常。
        all.join();

        System.out.println("stringListSuccess:   " + stringListSuccess);
        System.out.println("stringListFail:      " + stringListFail);

        long endTime = System.currentTimeMillis();
        System.out.println("StringBuffer的append用时:" + ((endTime - starTime) / 1000) + "秒");
    }

    /**
     * 同步执行
     */
    public static void syncRequest() {
        long starTime = System.currentTimeMillis();

        List<String> stringListSuccess = new ArrayList<>();
        List<String> stringListFail = new ArrayList<>();

        for (int i = 0; i < 5; i++) {
            String string = HttpUtils.sendGet("http://127.0.0.1:8080/tomorrow/paypal/createOrder", "code=" + i);
            JSONObject requestParams = JSONObject.parseObject(string);
            if ("200".equals(requestParams.getString("code"))) {
                stringListSuccess.add(requestParams.getString("data"));
            } else {
                stringListFail.add(requestParams.getString("data"));
            }
        }

        log.info("stringListSuccess: {}", stringListSuccess);
        log.info("stringListFail: {}", stringListFail);

        long endTime = System.currentTimeMillis();
        System.out.println("StringBuffer的append用时:" + ((endTime - starTime) / 1000) + "秒");
    }
}

3、打印截图

异步执行结果

asynchronousRequest:
java 异步请求completablefuture_异步

同步执行结果

java 异步请求completablefuture_json_02

4、备注

1、从截图中我们可以看出, 同步执行所需要的时间为10秒钟, 而异步执行的时间只需要2秒钟, 可以为我们节省8秒钟的时间, 这个时间不算短了

2、CompletableFuture是JDK1.8的特性, 具体内容可参考JDK1.8的文档中文文档: https://www.matools.com/api/java8