关于CompletableFuture的自己理解和使用

    public static void main(String[] args) throws InterruptedException, ExecutionException {
//        SpringApplication.run(MyApplication.class, args);
//        String a="123";
//        Integer b=789;
//        double a1=System.nanoTime()/1e13;

//        CompletableFuture<String> threadA=CompletableFuture.supplyAsync()

//            ExecutorService executorService= Executors.newFixedThreadPool(3);
//            //supplyAsync()可以定义返回值,现在使用的runAsync()由于传入的是Rnnable接口,是没有返回值的
//            CompletableFuture<Void> exceptionally = CompletableFuture.runAsync(() -> {
//                System.out.println("dfgdgfdj");
//
//            }).whenComplete((r, e) -> {
//                System.out.println("执行结果为"+r);
//                //System.out.println("打印的异常为"+e.getMessage());
//            }).exceptionally(e -> {
//                e.printStackTrace();
//                System.out.println("ddsdsd");
//                return null;
//            });
//        System.out.println("exceptionally.get() = " + exceptionally.get());
//        TimeUnit.SECONDS.sleep(3);//线程阻塞的方法
//
//        CompletableFuture.supplyAsync(()->{
//                    return "ssss";
//        }).thenApply(s -> {
//            return "ssss+thenApply";
//        });



      //相当于 new Thread()类来实现多线程
        // 1.supplyAsync 有返回值
        //2.并且可以通过一个对象来接收,并调用get()方法来获取异步的结果
        //类比于callAble接口
        CompletableFuture<String> supplyAsyncTest = CompletableFuture.supplyAsync(() -> {
//            int a=1/0;
            return "tset";
        });
        //supplyAsyncTest.get();

        //CompletableFuture.runAsync  相当于会启动一个线程。runAsync 无返回值
        //类比于runable接口
        CompletableFuture<Void> runAsyncTest = CompletableFuture.runAsync(() -> {

        });


        //当有一个新的异步任务需要依赖于第一个异步任务的结果时,
        // 比如需要先获取到supplyAsyncTest的结果后,再进行操作
        //thenApply 有入参,有返回值
        //thenAccept 有入参  无返回值
        //thenRun  无入参  无返回值
        //三个方法都会返回一个新的CompletableFuture对象
        //缺点是 没法捕获异常
        CompletableFuture<Boolean> booleanCompletableFuture = supplyAsyncTest.thenApply(t -> {
            return true;
        });

        supplyAsyncTest.thenAccept(t->{
            if (t.equals("")){

            }
        });
        supplyAsyncTest.thenRun(()->{
            //throw new Exception();
            System.out.println("\"thenRun\" = " + "thenRun");
        });

        //当需要一个新的异步任务  需要对上一个的异步任务的结果和异常都进行捕获时,
        // 可以使用whenComplete 和handle方法 他们的区别是 whenComplete 只有入参无返回值
        // handle方法 可以有入参和 返回值
        //目前比如来说一个新的异步任务,需要使用supplyAsyncTest的返回值时和异常时,可以使用whenComplete方法
        //whenComplete 和handle都会开启一个新的异步线程
        supplyAsyncTest.whenComplete((t,e)->{
            System.out.println(" 之前的任务的返回结果是 t = " + t);
            System.out.println("之前的任务的异常结果是 e = " + e);
        });

        supplyAsyncTest.handle((returnMes,e)->{
           return  returnMes;
        });
        //上面的方法是针对 一个异步任务需要依赖之前的执行结果时,才会用到的方法
        //总结一下: 只使用结果,不关注异常(或者保证不会异常的时候)可以用thenApply,thenAccept,thenRun方法
        //区别是 thenApply 同时支持入参,有返回值 thenAccept 有入参无返回值  thenRun无入参和无返回值
        //当需要同时关注 返回结果和异常时,可以使用whenComplete 和 handle方法
        // 区别是 handle有返回值 whenComplete无返回值
        //----------------------------------------------------------------------------------------



        //当需要对两个并无关系的异步任务进行编排时,并且两个任务都成功时才会进行下一步的,
        // 否则一个出现异常,会将异常结果作为返回值
        // thenComebine, 有入参,一个参数是新的异步任务,第二个参数是两个异步任务的执行结果,有返回值
        // thenAcceptBoth,有入参,一个参数是新的异步任务,第二个参数是两个异步任务的执行结果,无返回值
        // runAfterBoth,无入参,无返回值
        CompletableFuture<String> taskAlone1 = CompletableFuture.supplyAsync(() -> {
            try {
                TimeUnit.SECONDS.sleep(5);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "两个单独的任务需要全部完成时,这是第一个";
        });

        CompletableFuture<String> taskAlone2 = CompletableFuture.supplyAsync(() -> {
            try {
                TimeUnit.SECONDS.sleep(3);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "这是第二个异步任务";
        });


//        taskAlone1.thenCombine(taskAlone2,(t1,t2)->{
//            return t1+t2;
//        });
//
//        taskAlone1.thenAcceptBoth(taskAlone2,(t1,t2)->{
//            System.out.println("t1+t2+\"thenAcceptBoth\" = " + t1 + t2 + "thenAcceptBoth");
//        });
//
//        taskAlone1.runAfterBoth(taskAlone2,()->{
//            System.out.println("\"runAfterBoth\" = " + "runAfterBoth");
//        });

        //这里还有一个thenCompose方法  他和combine的区别是 combine 会直接使用两个异步任务的返回值,而compose会返回一个completeFuture对象
        //当两个异步任务有先后顺序时,可以用compose  如果两个任务是并行的,可以用combine
        //另外compose 可以无限的链式调用,可以将多个异步任务组合起来。
        taskAlone1.thenCompose(taskAlone1Result->{
            return  CompletableFuture.supplyAsync(()->{
                return taskAlone1Result+"";
            });
        });



        //当只需要对两个任务其中的一个执行成功即可时,可以使用applyToEither,acceptEither,runAfterEither
        //区别:applyToEither会将已经完成任务的执行结果作为所提供函数的参数,且该方法有返回值;acceptEither同样将已经完成任务的执行结果作为方法入参,但是无返回值;runAfterEither没有入参,也没有返回值。
//        taskAlone1.applyToEither(taskAlone2, t->{
//           return   t.toString();
//        });
//
//        taskAlone1.acceptEither(taskAlone2,t->{
//            System.out.println("t = " + t);
//        });
//
//        taskAlone1.runAfterEither(taskAlone2,()->{
//            System.out.println("\"runAfterEither\" = " + "runAfterEither");
//        });


        //当有更多个异步任务时,并且都需要等待他们完成时,可以使用allOf,anyOf
        CompletableFuture.allOf(taskAlone1, taskAlone2);
        String s1 = taskAlone1.get();
        String s2 = taskAlone2.get();


        System.out.println("s1 = " + s1);
        System.out.println("s2 = " + s2);

        CompletableFuture<Object> voidCompletableFuture = CompletableFuture.anyOf(taskAlone1, taskAlone2);
        Object o = voidCompletableFuture.get();
        System.out.println("o = " + o);
    }
  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值