案例说明:电商比价需求
代码实现如下:
public class CompletableFutureNetMallDemo {
static List<NetMall> mallList = Arrays.asList(
new NetMall("jd"),
new NetMall("tb"),
new NetMall("tm"),
new NetMall("dw"),
new NetMall("pdd")
);
//同步方式
public static List<String> getPriceByStep(List<NetMall> list,String productName) {
return list.stream()
.map(netMall -> String.format(productName + " in %s price is %.2f", netMall.getMallName(),netMall.calcPrice(productName)))
.collect(Collectors.toList());
}
//异步方式
public static List<String> getPriceByAsycn(List<NetMall> list,String productName) {
return list.stream()
.map(netMall -> CompletableFuture.supplyAsync(() -> String.format(productName + " in %s price is %.2f", netMall.getMallName(),netMall.calcPrice(productName))))
.collect(Collectors.toList())
.stream().map(CompletableFuture::join).collect(Collectors.toList());
}
public static void main(String[] args) {
System.out.println("-------------同步方式---------------");
long startTime = System.currentTimeMillis();
List<String> list = getPriceByStep(mallList, "java");
for (String element : list) {
System.out.println(element);
}
long endTime = System.currentTimeMillis();
System.out.println("-----花费时间为:"+ (endTime - startTime)+"毫秒-----");
System.out.println("-------------异步方式---------------");
long startTime2 = System.currentTimeMillis();
List<String> list2 = getPriceByAsycn(mallList, "java");
for (String element : list2) {
System.out.println(element);
}
long endTime2 = System.currentTimeMillis();
System.out.println("-----花费时间为:"+ (endTime2 - startTime2)+"毫秒-----");
}
}
class NetMall {
private String mallName;
public NetMall(String mallName){
this.mallName = mallName;
}
public double calcPrice(String productName){
//模拟检索时间1s
try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); }
return ThreadLocalRandom.current().nextDouble() * 2 + productName.charAt(0);
}
public String getMallName() { return mallName; }
}
结果测试
总结
如果现在有一些网站物品价格初始数据串,我们想要进行比价,可以将这些数据保存到Redis的Zset里边,保证数据没有重复,然后进行比较,第一种笨办法就是一条数据一条数据的过,但是这样性能不高;第二种,在JUC里边,有一个 CompletableFuture,用他做多线程异步并发是不阻塞的,而且可以自定义线程池,线程池根据数据量的大小伸缩,在数据量变大时仍能保证效率,大大提升程序性能。