如果任务的执行方式逻辑比较复杂,开发成本来说比较高。CompletableFuture就是帮你处理这些任务之间的逻辑关系,编排好任务的执行方式后,任务会按照规划好的方式一步一步执行,不需要让业务线程去频繁的等待。
- runAsync() 和 supplyAsync() 方法
// runAsync() 方法没有返回值
CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
int i = 10 / 2;
System.out.println("运行结束" + i);
}, service);
// supplyAsync() 方法有返回值
CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> {
int i = 10 / 0;
System.out.println("运行结束" + i);
return i;
}, service);
- thenAcceptAsync、thenApplyAsync、 thenRunAsync 方法
有任务A,任务B,任务B需要在任务A执行完毕后再执行。
CompletableFuture.supplyAsync(() -> {
int i = 10 / 2;
System.out.println("运行结束" + i);
return i;
// thenAccept() 接受前置任务结果,没有返回结果
}, service).thenAccept(res -> System.out.println("thenAccept():" + res))
// thenApply() 接受前置任务结果,且有返回结果
.thenApply(res -> {
System.out.println("thenApply:" + res);
return 1;
// thenRun() 即不接收前置任务结果,也没有返回结果
}).thenRun(() -> System.out.println("thenRun:12"));
// ....
thenApply执行使用的是主线程,可能导致堵塞
3.thenCombine,thenAcceptBoth,runAfterBoth(三者区别同上)
有任务A,任务B,任务C。任务A和任务B并行执行,等到任务A和任务B全部执行完毕后,再执行任务C。
A and B ----C
CompletableFuture<Integer> taskC = CompletableFuture.supplyAsync(() -> {
System.out.println("任务A");
return 78;
}).thenCombine(CompletableFuture.supplyAsync(() -> {
System.out.println("任务B");
return 66;
}), (resultA, resultB) -> {
System.out.println("任务C");
int resultC = resultA + resultB;
return resultC;
});
- applyToEither,acceptEither,runAfterEither
有任务A,任务B,任务C。任务A和任务B并行执行,只要任务A或者任务B执行完毕,开始执行任务C
A or B ----- C
CompletableFuture<Void> future2 = CompletableFuture.supplyAsync(() -> {
System.out.println("任务A");
return 78;
}).runAfterEither(CompletableFuture.supplyAsync(() -> {
System.out.println("任务B");
return 66;
}), () -> {
System.out.println("任务C");
});
- allOf,anyOf
allOf的方式是让内部编写多个CompletableFuture的任务,多个任务都执行完后,才会继续执行你后续拼接的任务
CompletableFuture<Void> future1 = CompletableFuture.allOf(future, future2);
// CompletableFuture<Object> future1 = CompletableFuture.anyOf(future, future2);
// get()和join()都是阻塞至线程结束,差别不大
// future1.get();
future1.join();
- exceptionally
CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> {
int i = 10 / 0;
System.out.println("运行结束" + i);
return i;
}, service).whenComplete((result, ex) -> {
// 这一行,即便在上面出现异常的情况下也会执行。
System.out.println("异步任务成功完成了... 结果:" + result);
}).exceptionally(ex -> {
System.out.println(ex.getMessage());
return -1;
});