CompletableFuture thenCompose和thenCombine的区别
一、 thenCompose
1. thenCompose的特点
thenCompose 可以用于组合多个CompletableFuture,将前一个任务的返回结果作为下一个任务的参数,它们之间存在着业务逻辑上的先后顺序。
thenCompose方法会在某个任务执行完成后,将该任务的执行结果作为方法入参然后执行指定的方法,该方法会返回一个新的CompletableFuture实例。
2. thenCompose的定义
public <U> CompletableFuture<U> thenCompose(Function<? super T, ? extends CompletionStage<U>> fn);
public <U> CompletableFuture<U> thenComposeAsync(Function<? super T, ? extends CompletionStage<U>> fn) ;
public <U> CompletableFuture<U> thenComposeAsync(Function<? super T, ? extends CompletionStage<U>> fn, Executor executor) ;
3. thenApply和thenCompose的区别
thenApply()转换的是泛型中的类型,相当于将CompletableFuture<T> 转换生成新的CompletableFuture<U>
thenCompose()用来连接两个CompletableFuture,是生成一个新的CompletableFuture。
下面对thenApply的测试代码进行修改,注意下图中区别
- thenCompose生成了一个新的CompletableFuture
- thenApply从CompletableFuture<Dept>生成新的CompletableFuture<User>。
public class Thread06_SupplyAsync_ThenCompose {
public static void main(String[] args) throws ExecutionException, InterruptedException {
DeptService deptService = new DeptService();
UserService userService = new UserService();
User user = new User(1, "冬哥", 31);
CompletableFuture<User> userCompletableFuture = CompletableFuture.supplyAsync(() -> {
Dept dept = deptService.getById(1);
return dept;
})
.thenCompose(dept -> CompletableFuture.supplyAsync(() -> {
//注意这里用到了上个线程的返回值dept
user.setDeptId(dept.getId());
user.setDeptName(dept.getName());
return userService.save(user);
}));
System.out.println("线程:" + Thread.currentThread().getName() +
" 结果:" + userCompletableFuture.get().toString());
}
}
运行结果如下:
线程:ForkJoinPool.commonPool-worker-1 getById(1)
线程:ForkJoinPool.commonPool-worker-1 save(),User{id=1, name='冬哥', age=31, DeptId=1, DeptName='研发一部'}
线程:main 结果:User{id=1, name='冬哥', age=31, DeptId=1, DeptName='研发一部'}
二、thenCombine
thenCombine会在两个任务都执行完成后,把两个任务的结果合并。
注意:
- 两个任务中只要有一个执行异常,则将该异常信息作为指定任务的执行结果。
- 两个任务是并行执行的,它们之间并没有先后依赖顺序。
public class Thread10_ThenCombine {
public static void main(String[] args) throws ExecutionException, InterruptedException {
DeptService deptService = new DeptService();
UserService userService = new UserService();
//第1个任务:获取id=1的部门
CompletableFuture<Dept> deptFuture = CompletableFuture
.supplyAsync(() -> {
return deptService.getById(1);
}
);
//第2个任务:获取id=1的人员
CompletableFuture<User> userFuture = CompletableFuture
.supplyAsync(() -> {
try {
//int a = 1 / 0;//出了异常就报错
return userService.getById(1);
} catch (Exception e) {
e.printStackTrace();
}
return null;
});
//将上面2个任务的返回结果dept和user合并,返回新的user
CompletableFuture<User> resultFuture = deptFuture
.thenCombine(userFuture,
new BiFunction<Dept, User, User>() {
@Override
public User apply(Dept dept, User user) {
user.setDeptId(dept.getId());
user.setDeptName(dept.getName());
return userService.save(user);
}
}
);
System.out.println("线程:" + Thread.currentThread().getName() + " 结果:" + resultFuture.get());
}
}
运行结果如下:
线程:ForkJoinPool.commonPool-worker-1 Dept.getById(1)
线程:ForkJoinPool.commonPool-worker-1 User.getById(1)
线程:main User.save(),User(id=1, name=冬哥, age=31, deptId=1, deptName=研发一部)
线程:main 结果:User(id=1, name=冬哥, age=31, deptId=1, deptName=研发一部)