Java8 CompletableFuture(6) 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=研发一部)
  • 9
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 8
    评论
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

瑟 王

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值