CompletableFuture使用方法
前言
- LogUtils为日志类用于按指定格式输出基本信息
- RandomUtils为随机数生成类,通过给定的范围生成随机数
场景说明
查询商品,并通过商品查询价格
查询商品方法
static String queryCode(String message){
LogUtils.info("queryCode start, message = {}", message);
try{
TimeUnit.MILLISECONDS.sleep(RandomUtils.nextInt(0, 1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
LogUtils.info("queryCode end, message = {}", message);
return "query";
}
通过商品名称查询商品价格
static Double fetchPrice(String code, String message){
LogUtils.info("fetchPrice start, code = {}, message = {}", code, message);
try{
TimeUnit.MILLISECONDS.sleep(RandomUtils.nextInt(0, 100));
} catch (InterruptedException e) {
e.printStackTrace();
}
LogUtils.info("fetchPrice end, code = {}, message = {}", code, message);
return RandomUtils.nextDouble(0, 100);
}
查询方法通过sleep语句模拟其他操作,message用于区分不同的查询来源,并且在执行前与执行后输出日志确认任务执行的先后顺序。
主查询程序
CompletableFuture<String> future0 = CompletableFuture.supplyAsync(() ->
queryCode("future0")
);
CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() ->
queryCode("future1")
);
CompletableFuture<Object> anyOf = CompletableFuture.anyOf(future0, future1);
CompletableFuture<Double> apply0 = anyOf.thenApplyAsync((result) ->
fetchPrice((String) result, "apply0")
);
CompletableFuture<Double> apply1 = anyOf.thenApplyAsync((result) ->
fetchPrice((String) result, "apply1")
);
CompletableFuture<Object> anyOf1 = CompletableFuture.anyOf(apply0, apply1);
anyOf1.thenAccept((result)->LogUtils.info("result = {}", result));
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
其中使用了supplyAsync、anyOf以及thenApplyAsync方法,下面我将介绍supplyAsync方法的作用。
- supplyAsync
通过指定的Supplier生成一个异步获取结果的CompletableFuture。 - anyOf
将多个CompletableFuture合并,当其中CompletableFuture获取数据成功后,合并后的CompletableFuture获取数据并返回执行下一步操作 - thenApplyAsync
添加链式Function类型操作异步操作,当指定的CompletableFuture执行完毕后链式执行的下一步操作。 - thenAccept
添加链式Consumer类型操作,当指定的CompletableFuture执行完毕后链式执行的下一步操作。
操作结果
queryCode(future1) => fetchPrice(apply0) => result => fetchPrice(apply1) => queryCode(future0)
执行完毕的顺序如上,当通过anyOf连接的两个CompletableFuture存在一个执行完毕后,就会进入链式操作的下一步即fetchPrice,然后等待fetchPrice的其中一个执行完毕后,获得结果。因此可以做出流程图如下。