JUC并发编程 CompletableFuture 业务代码实战
1 需求
电商网站比价需求分析:
1.1 需求说明:
a. 同一款产品,同时搜索出同款产品在各大电商平台的售价
b. 同一款产品,同时搜索出本产品在同一个电商平台下,各个入驻卖家售价是多少
1.2 输出返回:
a. 出来结果希望是同款产品的在不同地方的价格清单列表,返回一个List
例如:《Mysql》 in jd price is 88.05 《Mysql》 in taobao price is 90.43
1.3 解决方案,对比同一个产品在各个平台上的价格,要求获得一个清单列表
a. step by step,按部就班,查完淘宝查京东,查完京东查天猫....
b. all in,万箭齐发,一口气多线程异步任务同时查询》
2 代码
2.1 NetMall类
public class NetMall{
@Getter
private String netMallName;
public NetMall(String netMallName){
this.netMallName = netMallName ;
}
public double calcPrice(String productName){
try{TimeUnit.SECONDS.sleep(1);}catch (Exception e){e.printStackTrace();};
return ThreadLocalRandom.current().nextDouble() * 2 + productName.charAt(0);
}
}
2.2 CompletableFutureMallDemo 类
package com.kwfruit.thread.step01;
import lombok.Getter;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
/**
* 案例说明:电商比价需求,模拟如下情况:
* 1需求:
* 1.1 同一款产品,同时搜索出同款产品在各大电商平台的售价
* 1.2 同一款产品,同时搜索出本产品在同一个电商平台下,各个入驻卖家售价是多少
*
* 2输出:出来结果希望是同款产品的在不同地方的价格清单列表,返回一个List<String>
* 《mysql》 in jd price is 88.04
* 《mysql》 in taobao price is 88.03
* 《mysql》 in dangdang price is 88.03
*
*
*
*/
public class CompletableFutureMallDemo {
static List<NetMall> list = Arrays.asList(
new NetMall("jd"),
new NetMall("taobao"),
new NetMall("dangdang"));
/**
* 传统方法 一步一步循环算
*/
public static List<String> getPrice(List<NetMall> list,String productName){
return list.stream()
.map(netMall -> String.format(productName + "in %s price is %.2f", netMall.getNetMallName(),
netMall.calcPrice(productName))).collect(Collectors.toList());
}
/**
* 用CompletableFuture 异步进行计算
* @param list
* @param productName
* @return
*/
public static List<String> getPriceByCompletableFuture(List<NetMall> list,String productName){
return list.stream()
.map(netMall -> CompletableFuture.supplyAsync(()->String.format(productName + "in %s price is %.2f", netMall.getNetMallName(),
netMall.calcPrice(productName))))
.collect(Collectors.toList()).stream()
.map(s->s.join())
.collect(Collectors.toList());
}
public static void main(String[] args) {
long startTime = System.currentTimeMillis();
List<String> mysqlList = getPrice(list, "mysql");
// List<String> mysqlList = getPriceByCompletableFuture(list, "mysql");
for (String element: mysqlList){
System.out.println(element);
}
long endTime = System.currentTimeMillis();
System.out.println("---costTime:"+(endTime - startTime) + "毫秒");
}
}
3 性能测试
3.1 step by step 一步一步算 计算时长
3089毫秒
3.2 万箭齐发 用CompletableFuture异步计算 计算时长
1094毫秒 !!!
4 总结
从上面看出CompletableFuture可以极大的提高我们的运算效率,因此在一些业务代码中我们可以合理的运用CompletableFuture来优化我们的程序。