「这是我参与11月更文挑战的第21天,活动详情查看:2021最后一次更文挑战」
CompletableFuture
通过前面的两个future 的demo,我们发现了个问题,我们无法知道任务什么时候完成.
要么通过get的阻塞等待,或者isDone自旋判断是否完成,这两个都不是完整版的future.
jdk8 新增了CompletableFuture类.
其中,可以分成这么几类
💡 连续关系即连续执行.使用then 前缀.
条件同时满足,包含combine或者both
其一满足即可,包含Either
demo
1.可以直接通过runAsync方法异步执行Runable内容,类似new Thread(new Runable()),没有返回值
// 异步执行runable,没有返回结果
CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
System.out.println("家里电脑开始下载游戏"+LocalTime.now());
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("4小时下载完成 : " + LocalTime.now());
});
2.通过supplyAsync方法异步执行Callable内容,有返回值
// supplyAsync 有返回值
CompletableFuture<String> integerCompletableFuture = CompletableFuture.supplyAsync(() -> {
System.out.println("家里电脑开始下载游戏" + LocalTime.now());
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// System.out.println("4小时下载完成 : " + LocalTime.now());
return ("4小时下载完成 : " + LocalTime.now());
});
System.out.println(integerCompletableFuture.get());
3..使用链式编程,在异步执行后面跟上.thenApply(Function) 即可在任务1完成立即执行任务2,并传递任务1返回的参数.
thenApply有返回结果
注意:这两个任务不一定使用的同一个线程.
CompletableFuture<Integer> integerCompletableFuture1 = CompletableFuture.supplyAsync(() -> {
int hour = LocalTime.now().getHour();
System.out.println("future1返回当前的小时为 : " + hour);
return hour;
})
// 通过thenApply可以获取前一个future返回的结果
.thenApply(t -> {
System.out.println("future2接收的当前小时为 : " + t);
return t + 2;
});
4.thenAccept 接收参数,不用返回结果
CompletableFuture<Void> integerCompletableFuture1 = CompletableFuture.supplyAsync(() -> {
int hour = LocalTime.now().getHour();
System.out.println("future1返回当前的小时为 : " + hour);
return hour;
})
// 通过thenApply可以获取前一个future返回的结果,有返回结果
.thenAccept(t -> {
System.out.println("future2接收的当前小时为 : " + t);
});
5.thenRun 不接受参数,不返回结果
CompletableFuture<Void> integerCompletableFuture1 = CompletableFuture.supplyAsync(() -> {
int hour = LocalTime.now().getHour();
System.out.println("future1返回当前的小时为 : " + hour);
return hour;
})
// 通过thenApply可以获取前一个future返回的结果,有返回结果
.thenAccept(t -> {
System.out.println("future2接收的当前小时为 : " + t);
}).thenRun(()->{
System.out.println("future3完成的当前时间" + LocalTime.now());
});
6.thenCombine 处理两个独立的CompletableFuture结果
final int size = 10;
final int level = 2;
CompletableFuture<Integer> integerCompletableFuture3 = CompletableFuture.supplyAsync(() -> {
//计算面积
int area = size * 10;
return area;
});
CompletableFuture<Integer> integerCompletableFuture2 = CompletableFuture.supplyAsync(() -> {
// 计算价格
int price = (int) (level * 2);
return price;
});
// thenCombine 聚合两个独立的completableFuture
CompletableFuture<Double> doubleCompletableFuture = integerCompletableFuture3.thenCombine(integerCompletableFuture2, (t1, t2) -> {
System.out.println("价格为 : " + t2);
System.out.println("面积为 : " + t1);
double total = t1 * t2;
System.out.println("总价为 : " + total);
return total;
});
System.out.println(doubleCompletableFuture.get());
7.allOf 等待所有任务结束
// allOf 等待所有任务结束
CompletableFuture<Void> future1 = CompletableFuture.allOf(integerCompletableFuture3, integerCompletableFuture2);
System.out.println(future1.get());