ComplatebleFuture组合式异步编程

package com.example.thread.juc.completablefuture;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

import static java.lang.System.currentTimeMillis;
import static java.lang.System.out;

/**
 * completableFuture Java中的并发线程工具类
 *
 * 适用于
 *  存在线程之间相互依赖,等待线程结果,线程之间关联,异步回调
 *  线程之间And关系,或者 or 关系,
 *
 */
public class ExampleCompletableFuture {

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        //completableFutureSupplyAsync();
        //completableFutureRunAsync();
        //completableFutureSupplyAsyncAndThenApply();
        //completableFutureSupplyAsyncAndThenApplyAsync();
        //completableFutureSupplyAsyncAndExceptionally();
        //completableFutureSupplyAsyncAndWhenComplete();
        //completableFutureCombine();
        //completableFutureEither();
        completableFutureCompPost();
    }

    //================================异步回调===DEMO===begin================================================
    /**
     * CompletableFuture.supplyAsync 与线程池中的 Executor.submit(Future ) 异步带有返回值的逻辑一致
     * supplyAsync(任务);//带有返回值的异步执行,通过 get()阻塞调用线程
     *
     */
    public static void completableFutureSupplyAsync() throws ExecutionException, InterruptedException {
        CompletableFuture<Double> cf = CompletableFuture.supplyAsync(() -> {
            long l = currentTimeMillis();
            out.println("supplyAsync" + l);
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            out.println("cha:" + (currentTimeMillis() - l));
            return 1.2;
        });
        out.println("lol");
        Double aDouble = cf.get();
        out.println("CompletableFuture" + aDouble);
    }

    /**
     * CompletableFuture.runAsync 和线程池中 submit(Runnable) 逻辑一致,只会执行任务,不带返回值
     * get()方法还是会阻塞调用线程
     * @throws ExecutionException
     * @throws InterruptedException
     */
    public static void completableFutureRunAsync() throws ExecutionException, InterruptedException {
        CompletableFuture<Void> voidCompletableFuture = CompletableFuture.runAsync(() -> {
            out.println("begin");
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            out.println("end");
        });
        Void aVoid = voidCompletableFuture.get();
        out.println("void");
    }

    /**
     * completableFuture.supplyAsync后调用thenApply实现细节是:
     *  异步回调,thenApply中的任务会等待supply中的任务返回结果后才会执行且thenApply也需要返回结果
     *      thenApply执行的线程是supplyAsync中的线程继续执行的,没有重新创建线程执行thenApply中的任务
     *  同样调用 get()方法会阻塞调用线程,返回结果时唤醒调用get线程,
     * @throws ExecutionException
     * @throws InterruptedException
     */
    public static void completableFutureSupplyAsyncAndThenApply() throws ExecutionException, InterruptedException {
        CompletableFuture<String> cf = CompletableFuture.supplyAsync(() -> {
            out.println("["+Thread.currentThread().getName() + " ]first SupplyAsync");
            try {
                //为什么使用 Sleep,模拟业务逻辑执行时间
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            out.println("first SupplyAsync Sleep End");
            return "first SupplyAsync";
        });
        CompletableFuture<String> cf2 = cf.thenApply(s -> {
            out.println("["+Thread.currentThread().getName() + "]thenApply");
            try {
                //为什么使用 Sleep,模拟业务逻辑执行时间
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            out.println("thenApply Sleep end");
            return s + " thenApply";
        });
        out.println("main begin");
        String s = cf.get();//阻塞 等待cf执行完成
        out.println("cf result:"+s);
        String s1 = cf2.get();
        out.println("c2 result:" + s1);
        out.println("main end");
    }

    /**
     * completableFuture.supplyAsync后调用thenApply实现细节是:
     *  异步回调,thenApplyAsync中的任务会等待supply中的任务返回结果后才会执行且thenApply也需要返回结果
     *      thenApplyAsync执行的线程是有可能重新启动线程执行里面的任务,也有可能是supply中的线程继续执行
     *
     *  同样调用 get()方法会阻塞调用线程,返回结果时唤醒调用get线程,
     * @throws ExecutionException
     * @throws InterruptedException
     */
    public static void completableFutureSupplyAsyncAndThenApplyAsync() throws ExecutionException, InterruptedException {
        CompletableFuture<String> cf = CompletableFuture.supplyAsync(() -> {
            out.println("["+Thread.currentThread().getName() + " ]first SupplyAsync");
            try {
                //为什么使用 Sleep,模拟业务逻辑执行时间
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            out.println("first SupplyAsync Sleep End");
            return "first SupplyAsync";
        });
        CompletableFuture<String> cf2 = cf.thenApplyAsync(s -> {
            out.println("["+Thread.currentThread().getName() + "]thenApply");
            try {
                //为什么使用 Sleep,模拟业务逻辑执行时间
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            out.println("thenApply Sleep end");
            return s + " thenApply";
        });
        out.println("main begin");
        String s = cf.get();//阻塞 等待cf执行完成
        out.println("cf result:"+s);
        String s1 = cf2.get();
        out.println("c2 result:" + s1);
        out.println("main end");
    }

    /**
     * completableFuture.supplyAsync后调用thenApply实现细节是:
     *  异步回调,thenApplyAsync中的任务会等待supply中的任务返回结果后才会执行且thenAccept接收supply值,不需要返回结果
     *      thenApplyAsync执行的线程是有可能重新启动线程执行里面的任务,也有可能是supply中的线程继续执行
     *
     *  同样调用 get()方法会阻塞调用线程,返回结果时唤醒调用get线程,
     * @throws ExecutionException
     * @throws InterruptedException
     */
    public static void completableFutureSupplyAsyncAndThenAccept() throws ExecutionException, InterruptedException {
        CompletableFuture<String> cf = CompletableFuture.supplyAsync(() -> {
            out.println("["+Thread.currentThread().getName() + " ]first SupplyAsync");
            try {
                //为什么使用 Sleep,模拟业务逻辑执行时间
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            out.println("first SupplyAsync Sleep End");
            return "first SupplyAsync";
        });
        CompletableFuture<Void> cf2 = cf.thenAccept(s -> {
            out.println("["+Thread.currentThread().getName() + "]thenApply");
            try {
                //为什么使用 Sleep,模拟业务逻辑执行时间
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            out.println("thenApply Sleep end");
        });
        out.println("main begin");
        String s = cf.get();//阻塞 等待cf执行完成
        out.println("cf result:"+s);
        Void aVoid = cf2.get();
        out.println("main end" + aVoid);
    }
    /**
     * completableFuture.supplyAsync后调用thenRunAsync实现细节是:
     *  异步回调,thenRunAsync中的任务会等待supply中的任务返回结果后才会执行且thenRun "不" 接收supply值,不需要返回结果
     *      thenRunAsync执行的线程是有可能重新启动线程执行里面的任务,也有可能是supply中的线程继续执行
     *
     *  同样调用 get()方法会阻塞调用线程,返回结果时唤醒调用get线程,
     * @throws ExecutionException
     * @throws InterruptedException
     */
    public static void completableFutureSupplyAsyncAndThenRun() throws ExecutionException, InterruptedException {
        CompletableFuture<String> cf = CompletableFuture.supplyAsync(() -> {
            out.println("["+Thread.currentThread().getName() + " ]first SupplyAsync");
            try {
                //为什么使用 Sleep,模拟业务逻辑执行时间
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            out.println("first SupplyAsync Sleep End");
            return "first SupplyAsync";
        });
        CompletableFuture<Void> cf2 = cf.thenRun(() -> {
            out.println("["+Thread.currentThread().getName() + "]thenApply");
            try {
                //为什么使用 Sleep,模拟业务逻辑执行时间
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            out.println("thenApply Sleep end");
        });
        out.println("main begin");
        String s = cf.get();//阻塞 等待cf执行完成
        out.println("cf result:"+s);
        Void aVoid = cf2.get();
        out.println("main end" + aVoid);
    }

    /**
     * completableFuture.supplyAsync后调用exceptionally实现细节是:
     *  异步回调异常处理且有返回值,
     *      supply中执行任务出现异常,直接调用 exceptionally 异常处理,
     *      而supply后续的异步回调任务则不会调用后续的异步任务
     *
     *  同样调用 get()方法会阻塞调用线程,返回结果时唤醒调用get线程,
     * @throws ExecutionException
     * @throws InterruptedException
     */
    public static void completableFutureSupplyAsyncAndExceptionally() throws ExecutionException, InterruptedException {
        CompletableFuture<String> cf = CompletableFuture.supplyAsync(() -> {
            out.println("["+Thread.currentThread().getName() + " ]first SupplyAsync");
            try {
                //为什么使用 Sleep,模拟业务逻辑执行时间
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if(true){
                throw  new RuntimeException("throw Exceptionally supplyAsync");
            }else{
                out.println("first SupplyAsync Sleep End");
                return "first SupplyAsync";
            }
        });
        //exceptionally 会捕获 cf抛出的异常,然后进行处理 且可以返回自定义的结果
        CompletableFuture<String> cf2 = cf.exceptionally(ex -> {
            out.println(" enter exceptionally");
            try {
                //为什么使用 Sleep,模拟业务逻辑执行时间
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            ex.printStackTrace();
            out.println("out exceptionally");
            return "exceptionally";
        });
        CompletableFuture<String> cf3 = cf.thenApply(s -> {
            out.println("send thenApply");
            try {
                //为什么使用 Sleep,模拟业务逻辑执行时间
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            out.println("send thenApply Sleep End");
            return s + "thenApply";
        });
        out.println("main begin");
        String s = cf.get();
        out.println("cf result:" + s);
        String s1 = cf2.get();
        out.println("cf2 result:" + s1);
        String s2 = cf3.get();
        out.println("cf3 result:" + s2);
        out.println("main End");
    }

    /**
     * completableFuture.supplyAsync后调用whenComplete实现细节是:
     *  异步回调异常处理且有返回值,
     *      supply中执行任务出现异常,直接调用 whenComplete 有两个参数:a = supply的返回值,b = supply中抛出的异常
     *      whenComplete 默认返回 supply中的返回值,是同一个
     *
     * completableFuture.supplyAsync后调用handleAsync实现细节是:
     *  异步回调异常处理且有返回值,
     *      supply中执行任务出现异常,直接调用 whenComplete 有两个参数:a = supply的返回值,b = supply中抛出的异常
     *      whenComplete 默认返回 supply中的返回值,是不是同一个,有handler中自定义
     *
     * @throws ExecutionException
     * @throws InterruptedException
     */
    public static void completableFutureSupplyAsyncAndWhenComplete() throws ExecutionException, InterruptedException {
        CompletableFuture<String> cf = CompletableFuture.supplyAsync(() -> {
            out.println("first SupplyAsyncWhen");
            try {
                //为什么使用 Sleep,模拟业务逻辑执行时间
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if (true) {
                throw new RuntimeException("when Exception");
            } else {
                out.println("first SupplyAsyncWhen Sleep End");
                return "first SupplyAsyncWhen";
            }

        });
        CompletableFuture<String> cf2 = cf.whenComplete((a, b) -> {
            out.println("whenComplete enter");
            try {
                //为什么使用 Sleep,模拟业务逻辑执行时间
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if (b != null) {
                b.printStackTrace();
            }else{
                out.println("whenComplete a:"+a);
            }
        });
        /*CompletableFuture<String> stringCompletableFuture = cf.handleAsync((a, b) -> {

            System.out.println("handler enter");
            try {
                //为什么使用 Sleep,模拟业务逻辑执行时间
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if (b != null) {
                b.printStackTrace();
            }else{
                System.out.println("whenComplete a:"+a);
            }
            return "handler";
        });*/

        out.println("main begin");
        String s = cf2.get();
        out.println("cf2 :" + s);
    }

    //================================异步回调===DEMO===End================================================


    //================================组合处理===DEMO===begin================================================

    /**
     * =================thenCombine=====thenAcceptBoth===runAfterBoth==============
     *
     * thenCombine,是有两个带有返回值的 completableFuture组合,只有两个都执行完成,才会执行thenCombine中的任务
     *  两个supply是并行的,但是thenCombine 会等待两个执行完成才会执行,然后取得两个任务的返回值
     *
     *  thenCombine 需要自定义返回值,可获取到组合的返回值
     *  thenAcceptBoth 无返回值,可获取到组合的返回值
     *  runAfterBoth 无返回值,获取不到组合的返回值
     *  同样调用 get()方法会阻塞调用线程,返回结果时唤醒调用get线程,
     * @throws ExecutionException
     * @throws InterruptedException
     */
    public static void completableFutureCombine() throws ExecutionException, InterruptedException {
        CompletableFuture<Double> cf = CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return 13.0;
        });

        CompletableFuture<Double> cf2 = CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return 1.0;
        });

        //注意 组合明细必须使用 引用类型
        CompletableFuture<String> cf3=cf.thenCombine(cf2,(a,b)->{
            out.println("combine begin");
            out.println("job3 param a->"+a+",b->"+b);
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
            }
            out.println(Thread.currentThread()+" exit job3,time->"+ currentTimeMillis());
            return a + " " +b;
        });

        CompletableFuture<Void> voidCompletableFuture = cf.thenAcceptBoth(cf2, (a, b) -> {
            //可获取 a ,b的执行结果
            //无返回值
        });
        CompletableFuture<Void> voidCompletableFuture1 = cf.runAfterBoth(cf2, () -> {
            //获取不到 a , b 的结果
            //无返回值
        });
        out.println("main begin");
        String s = cf3.get();
        out.println("cf3 result:" + s);
    }

    /**
     * =================applyToEither=====AcceptToEither===runAfterEither==============
     *
     * applyToEither,是有两个带有返回值的 completableFuture组合,只有两个都执行完成,才会执行thenCombine中的任务
     *  两个supply是并行的,但是thenCombine 会等待两个执行完成才会执行,然后取得最先完成的任务的返回值(只有一个参数)
     *
     *  applyToEither 需要自定义返回值,可获取到组合的返回值(1个)
     *  AcceptToEither 无返回值,可获取到组合的返回值
     *  runAfterEither 无返回值,获取不到组合的返回值
     *  同样调用 get()方法会阻塞调用线程,返回结果时唤醒调用get线程,
     * @throws ExecutionException
     * @throws InterruptedException
     */
    public static void completableFutureEither() throws ExecutionException, InterruptedException {
        CompletableFuture<Double> cf = CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return 13.0;
        });

        CompletableFuture<Double> cf2 = CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return 1.0;
        });

        CompletableFuture<Double> cf3 = cf.applyToEither(cf2, (result) -> {
            out.println("Either begin");
            out.println("job3 param result->"+result);
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
            }
            out.println(Thread.currentThread()+" exit job3,time->"+ currentTimeMillis());
            return result;
        });

        cf.acceptEither(cf2,(result)->{
            //有参数
            //无返回值
        });
        cf.runAfterEither(cf2,()->{
           //无参数
           //无返回值
        });

        out.println("main begin");
        Double s = cf3.get();
        out.println("cf3 result:" + s);
    }

    /**
     * thenCompose 为等待cf执行完成后将参数传入到 thenCompose中执行,
     *  thenCompose 会返回 新的 CompletableFuture实例,
     * @throws ExecutionException
     * @throws InterruptedException
     */
    public static  void completableFutureCompPost() throws ExecutionException, InterruptedException {
        CompletableFuture<Double> cf = CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return 13.0;
        });
        CompletableFuture<String> cf2 = cf.thenCompose((e) -> {
            out.println("e:" + e );
            return CompletableFuture.supplyAsync(() -> {
                return "dfa";
            });
        });
        String s = cf2.get();
        out.println(s);
    }

    /**
     *  //allof等待所有任务执行完成才执行cf4,如果有一个任务异常终止,则cf4.get时会抛出异常,都是正常执行,cf4.get返回null
     *  //anyOf是只有一个任务执行完成,无论是正常执行或者执行异常,都会执行cf4,cf4.get的结果就是已执行完成的任务的执行结果
     *
     */
    public static void completableFutureAnyall(){
        CompletableFuture<String> cf = CompletableFuture.supplyAsync(() -> {
            return "cf";
        });
        CompletableFuture<String> cf1 = CompletableFuture.supplyAsync(() -> {
            return "cf1";
        });
        CompletableFuture<String> cf2 = CompletableFuture.supplyAsync(() -> {
            return "cf2";
        });

        CompletableFuture<Void> cf4 = CompletableFuture.allOf(cf, cf1, cf2).whenComplete((a, e) -> {

        });

        CompletableFuture<String> cf5 = CompletableFuture.anyOf(cf, cf1, cf2).thenCompose((e) -> {
            return CompletableFuture.supplyAsync(() -> "sdfsd");
        });
    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值