CompletableFuture可以做future做的事
CompletableFuture优点:
1.异步任务结束时,自动回调某个对象的方法;
2.异步任务出错时,自动回调某个对象的方法;
3.主线程设置好回调后,不再关心异步任务的执行,异步任务之间可以顺序执行。
多线程异步调用/异步编排(减少阻塞及轮询):
public static void main(String[] args) throws ExecutionException, InterruptedException {
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 20, 1L, TimeUnit.SECONDS,
new LinkedBlockingDeque<>(50), Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy());
// 两个异步任务,第二个异步任务依赖第一个异步任务做事。多个异步任务交互
java.util.concurrent.CompletableFuture.supplyAsync(()->{
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
return 1;
}).thenApply(f ->{
return f+2;
}).whenComplete((v,e)->{
if (e==null) System.out.println("results: "+v);
}).exceptionally(e->{
e.printStackTrace();
return null;
});
System.out.println("mainThread over");
// 主线程不要立刻结束,否则completableFuture的默认线程池会立刻关闭,so此处暂停3s
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
threadPoolExecutor.shutdown();
}
结果
mainThread over
results: 3
join() 和get()对比
二者本质一样,只不过join()不抛出异常,join同样导致阻塞。
public static void main(String[] args) throws ExecutionException, InterruptedException {
System.out.println(CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
return 1;
}).whenComplete((v, e) -> {
if (e == null) System.out.println("result: " + v);
}).exceptionally(e -> {
e.printStackTrace();
return null;
}).join());
System.out.println("main over");
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
★案例:比价需求
1.搜索统计同款商品在各大电商的售价
2.同一款产品,本产品在一个电商平台下,各个入驻门店的售价
结果希望是同款产品在不同地方的价格清单列表,返回一个List
public class CompletableFutureNetMallDemo {
// 不同电商平台
static List<NetMall> list = Arrays.asList(
new NetMall("jd"),
new NetMall("tmall"),
new NetMall("tb"),
new NetMall("dd"),
new NetMall("pdd")
);
// 一。 同步:step by step
public static List