继上章节(传送门>>>),本章继续介绍CompletableFuture其他方法的使用。
public static void main(String[] args) throws Exception {
// 6. 回调2.0【whenComplete,handle】
CompletableFuture<String> cf4 = CompletableFuture.supplyAsync(() -> {
System.out.println("6.业务过程=" + 1 / 1);
// System.out.println("6.业务过程=" + 1 / 0);
return "cf4正常执行返回";
}).whenComplete((result, exce) -> {
if (null != exce) {
// exce.printStackTrace();
System.out.println("异常信息=" + exce.getMessage());
} else {
System.out.println("6.回调2.0正常执行返回");
}
});
System.out.println(cf4.get());
/**
* 注: 和之前回调应用场景的区别
* 1.cf4任务是正常执行的,cf4.get()的结果就是cf4执行的结果
* 2.cf4任务是执行异常的,则cf4.get()会抛出异常
*
* handle与whenComplete用法类似,区别:
* 1:handle有返回值,whenComplete无返回值
* 2:handle有返回值且与cf4自身的返回无任何关系
*/
// 7.组合处理(1)【thenCombine、thenAcceptBoth、runAfterBoth】
/**
* 三个方法都是将两个CompletableFuture组合起来,两个都正常执行完了才会执行某个任务
* 区别:
* 1:thenCombine会将两个任务的返回值作为入参传递到目标方法中,且目标方法有返回值
* 2:thenAcceptBoth同样将两个任务的返回值作为目标方法入参,但目标方法无返回值
* 3:runAfterBoth没有入参,也没有返回值
*/
CompletableFuture<String> cf5_1 = CompletableFuture.supplyAsync(() -> {
// 任务1
return "cf5_1返回";
});
CompletableFuture<String> cf5_2 = CompletableFuture.supplyAsync(() -> {
// 任务2
return "cf5_2返回";
});
CompletableFuture<String> cf5_thenCombine = cf5_1.thenCombine(cf5_2, (a, b) -> {
// 有返回
return "7.组合处理【thenCombine】=" + a + " -- " + b;
});
System.out.println(cf5_thenCombine.get());
CompletableFuture<Void> cf5_thenAcceptBoth = cf5_1.thenAcceptBoth(cf5_2, (a, b) -> {
// 无返回
System.out.println("7.组合处理【thenAcceptBoth】=" + a + " -- " + b);
});
cf5_thenAcceptBoth.get();
CompletableFuture<Void> cf5_runAfterBoth = cf5_1.runAfterBoth(cf5_2, () -> {
// 无入参,无返回
System.out.println("7.组合处理【runAfterBoth】=" + "无入参,无返回");
});
cf5_runAfterBoth.get();
// 7.组合处理(2)【applyToEither、acceptEither、runAfterEither】
/**
* 三个方法都是将两个CompletableFuture组合起来,只要其中一个执行完了就会执行目标任务
* 区别:
* 1:applyToEither会将已经执行完成的任务的执行结果作为方法入参,并有返回值;
* 2:acceptEither同样将已经执行完成的任务的执行结果作为方法入参,但是没有返回值
* 3:runAfterEither没有方法入参,也没有返回值
*/
// 7.组合处理(1)和7.组合处理(2)的区别在于,执行目标任务的前提,前者必须全部正常执行,后者有一个执行完成
// 8.【allOf、anyOf】
CompletableFuture<String> task1 = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
}
return "Task1";
});
CompletableFuture<String> task2 = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(1500);
} catch (InterruptedException e) {
}
return "Task2";
});
CompletableFuture<String> task3 = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(2500);
} catch (InterruptedException e) {
}
return "Task3";
});
// 可以类似实现countdownLatch的功能,实现阻塞线程,等待子任务执行完成
CompletableFuture<Void> cf6 = CompletableFuture.allOf(task1, task2, task3);
// System.out.println(cf6.get(20, TimeUnit.MILLISECONDS));
System.out.println("cf6.get()=" + cf6.get());
/**
* 区别:
* 1:allof等待所有任务执行完成才执行cf6
* 2:anyOf是只有一个任务执行完成,无论是正常执行或者执行异常,都会执行cf6
*/
// allof:如果有一个任务异常终止,则cf6.get时会抛出异常,都是正常执行,cf6.get返回null
// anyOf:cf6.get的结果就是已执行完成的任务的执行结果
}
执行结果如图:
欢迎评论区指正和交流。