在博主前几篇博客中,https://blog.csdn.net/qq_52545155/article/details/128167519?spm=1001.2014.3001.5501,给大家分享了关于多线程中异步任务的执行和一些相关概念,在这篇博客中,主要是通过一个实际的案例让大家对于CompletableFuture的用法有一个深入的理解
临近过年了,很多铁子都有购物的需求,那么大家肯定想花更少的钱去买相同的一个产品,例如茅台酒在不同的购物平台或者不同的商家里面价格是不一样的,例如:
🍕jd:
🍕tb:
图中这些价格都是不一样的,所以大家就会有一个需求,能不能把这个当作一个程序进行一个数据统计,统计出不同平台的茅台价格,然后自己根据价格、商家来购买,这个例子大家都明白,其实在工作中也有很多这种的需求,那么针对这种需要统计的需求业务我们该怎么去做呢?
相信很多铁子有心里有方案:
class ShoppMall{private String mallName;public String getMallName() {return mallName;}public ShoppMall(String mallName) {this.mallName = mallName;}/*商城存在了,这里提供一个根据输入的商品名返回一个价格的方法*/public Double getPrice(String commodityName){//模拟检索用时1stry {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}//高并发多线程使用ThreadLocalRandomreturn ThreadLocalRandom.current().nextDouble()*2+commodityName.charAt(0);}}
public class CSDNCompletableFutureDemo {//实例化几个商城对象,放到集合中private static List list= Arrays.asList(new ShoppMall("jd"),new ShoppMall("tb"),new ShoppMall("pdd"));}
/*一个一个的从商城进行搜索一个商品,然后返回一个格式化好了的集合*/public static List stepSearch(List list,String comName){return list.stream().map(mall -> {System.out.println(mall.getMallName() + "正在查找" + comName);return String.format("%s 的 %s 价格是%.2f", mall.getMallName(), comName, mall.getPrice(comName));}).collect(Collectors.toList());}
public static void main(String[] args) {long startTime = System.currentTimeMillis();List search1 = stepSearch(list, "茅台");for (String s : search1) {System.out.println(s);}System.out.println("本次用时"+(System.currentTimeMillis()-startTime)+"毫秒");}
效果如下:
🚗总结:这里每一个商城搜索都用了1s,然后加上其他的耗时,一共是3061毫秒,代码着我有多少个平台,至少就要花n+秒的时间,显然这个很不能让人接收,那么在我们用Compleatable如何去实现呢,接着往下看;
/*用CompletableFuture异步多线程进行搜索,然后返回一个格式化好了的集合*/public static List synSearch(List list, String comName) {return list.stream().map(mall -> {System.out.println(mall.getMallName() + "正在查找" + comName);return CompletableFuture.supplyAsync(() -> {return String.format("%s 的 %s 价格是%.2f", mall.getMallName(), comName, mall.getPrice(comName));});}).collect(Collectors.toList()).stream().map(CompletableFuture::join).collect(Collectors.toList());}
运行代码:
public static void main(String[] args) {long startTime = System.currentTimeMillis();
// List search1 = stepSearch(list, "茅台");List search1 = synSearch(list, "茅台");for (String s : search1) {System.out.println(s);}System.out.println("本次用时" + (System.currentTimeMillis() - startTime) + "毫秒");}
效果图:
🚗总结:每个商城检索要一秒,而这种方式相当于是在一秒钟,多个商城同时进行搜索,然后将结果进行了返回,达到了万箭齐发的效果,这也正是我们想要的。