异步调用(多线程)

Future

一般不使用Future

Future 也是一个异步计算结果返回接口,目的获取返回值结果。但是 future 在获取返回值结构的时候,方法必须同步阻塞等待返回值结果。
     Get : 获取结果(等待,阻塞)
     Get(timeout) : 获取结果,指定等待时间
     Cancel : 取消当前任务
     isDone : 判断任务是否已经完成 (轮询)
futrure 对于结果获取不是很方便,只能通过同步阻塞的方式获取结果,或者是轮询的方式获取到结果;阻塞的方式获取返回值结果与异步的思想想违背,轮询方式又很占用 cpu 资源,也不能及时得到我们结果。

CompletableFuture

即异步编排

 CompletableFuture
      可以帮助我们简化异步编程复杂性,提供了函数式编程的能力,可以通过回调函数的方式处理计算结果。
 public class CompletableFuture<T> implements Future<T>, CompletionStage<T>
      CompletableFuture 具有Future 的特性,还实现了CompletionStage 接口,具备CompletionStage
      接口的特性: 串行执行,并行执行,聚合(AND 聚合,OR 聚合)
 1.串行关系执行
      then – 然后,也就是表示下一步,所以通常是一个串行的关系体现,then后面的单词(比如 run/apply/accept)就是函数是接口中抽象方法名称;
      利用上一步的执行结果,去进行下一步任务执行,任务执行具有先后顺序,因此把这种操作叫做串行关系
      public CompletionStage<Void> thenRun(Runnable action);
      public CompletionStage<Void> thenRunAsync(Runnable action);
      public CompletableFuture<Void> thenRunAsync(Runnable action,Executor executor);
      public <U> CompletableFuture<U> thenApply( Function<? super T,? extends U> fn) ;
      public <U> CompletionStage<U> thenApplyAsync(Function<? super T,? extends U> fn);
      public <U> CompletionStage<U> thenApplyAsync(Function<? super T,? extends U> fn,Executor executor);
      public CompletionStage<Void> thenAccept(Consumer<? super T> action);
      public CompletionStage<Void> thenAcceptAsync(Consumer<? super T> action);
      public CompletionStage<Void> thenAcceptAsync(Consumer<? super T>  action, Executor executor);
      public <U> CompletionStage<U> thenCompose(Function<? super T, ? extends CompletionStage<U>> fn);
      public <U> CompletionStage<U> thenComposeAsync(Function<? super T, ? extends CompletionStage<U>> fn);
      public <U> CompletionStage<U> thenComposeAsync(Function<? super T, ? extends CompletionStage<U>> fn, Executor executor);
 2.聚合and
 Combine…… with …… 和 both…… and …… 都是要求两者都必须满足,也就是and 且的关系。
      public <U,V> CompletionStage<V> thenCombine  (CompletionStage<? extends U> other, BiFunction<? super T,? super U,? extends V> fn);
      public <U,V> CompletionStage<V> thenCombineAsync  (CompletionStage<? extends U> other,  BiFunction<? super T,? super U,? extends V> fn);
      public <U,V> CompletionStage<V> thenCombineAsync (CompletionStage<? extends U> other,  BiFunction<? super T,? super U,? extends V> fn, Executor executor);
      public <U> CompletionStage<Void> thenAcceptBoth (CompletionStage<?  extends U> other, BiConsumer<? super T, ? super U> action);
      public <U> CompletionStage<Void> thenAcceptBothAsync (CompletionStage<? extends U> other, BiConsumer<? super T, ? super U> action);
      public <U> CompletionStage<Void> thenAcceptBothAsync(CompletionStage<? extends U> other, BiConsumer<? super T, ? super U> action,  Executor executor);
      public CompletionStage<Void> runAfterBoth(CompletionStage<?> other, Runnable action);
      public CompletionStage<Void> runAfterBothAsync(CompletionStage<?> other, Runnable action);
      public CompletionStage<Void> runAfterBothAsync(CompletionStage<?> other, Runnable action, Executor executor);
 3.聚合or
      public <U> CompletionStage<U> applyToEitherAsync (CompletionStage<? extends T> other, Function<? super T, U> fn);
      public <U> CompletionStage<U> applyToEitherAsync (CompletionStage<? extends T> other, Function<? super T, U> fn, Executor executor);
      public <U> CompletionStage<U> applyToEitherAsync (CompletionStage<? extends T> other, Function<? super T, U> fn);
      public <U> CompletionStage<U> applyToEitherAsync (CompletionStage<? extends T> other, Function<? super T, U> fn, Executor executor);
      public CompletionStage<Void> acceptEither (CompletionStage<? extends T> other, Consumer<? super T> action);
      public CompletionStage<Void> acceptEitherAsync (CompletionStage<? extends T> other, Consumer<? super T> action);
      public CompletionStage<Void> acceptEitherAsync (CompletionStage<? extends T> other, Consumer<? super T> action, Executor executor);
      public CompletionStage<Void> runAfterEither(CompletionStage<?> other, Runnable action);
      public CompletionStage<Void> runAfterEitherAsync (CompletionStage<?> other, Runnable action);
      public CompletionStage<Void> runAfterEitherAsync (CompletionStage<?> other, Runnable action, Executor executor);
 4.异常处理
      public CompletionStage<T> exceptionally(Function<Throwable, ? extends T> fn);
      public CompletionStage<T> whenComplete (BiConsumer<? super T, ? super Throwable> action);
      public CompletionStage<T> whenCompleteAsync (BiConsumer<? super T, ? super Throwable> action);
      public CompletionStage<T> whenCompleteAsync (BiConsumer<? super T, ? super Throwable> action, Executor executor);
      public <U> CompletionStage<U> handle (BiFunction<? super T, Throwable, ? extends U> fn);
      public <U> CompletionStage<U> handleAsync (BiFunction<? super T, Throwable, ? extends U> fn);
      public <U> CompletionStage<U> handleAsync (BiFunction<? super T, Throwable, ? extends U> fn, Executor executor);

异步开启

异步开启
     CompletableFuture 提供了 4 个静态的方法,来创建一个异步操作(异步开启: 从这 4 个静态的方法开发即可)
1.runAsync方法:
     没有返回值的方法,不关注返回值
     public static CompletableFuture<Void> runAsync(Runnable runnable);
     public static CompletableFuture<Void> runAsync(Runnable runnable,Executor executor);
2.supplyAsync :
     有返回值,关注返回值的。
     public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier);
     public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier,Executor executor)

案例:

方法说明
1.runAsync 没有返回值
2.1 public static CompletableFuture<Void> runAsync(Runnable runnable);  使用默认的线程池
2.2 public static CompletableFuture<Void> runAsync(Runnable runnable,  Executor executor) 自定义线程池
<p>
2.supplyAsync:    有返回值的,关注返回值
2.1 public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier) 使用默认的线程池
2.3 public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier,  Executor executor) 自定义线程池
<p>
3. thenRun 第一步执行完执行第二步,第二步的不关心第一执行的结果
3.1 public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)
3.2 public CompletableFuture<Void> thenRun(Runnable action)  不关心返回值,也不关心也行结果,只有顺序,1执行后2才会执行
<p>
4. thenApply 有返回值U,也关心上一步的返回值,上一步的返回值会被当成参数,参数类型为T,也是顺序执行,1执行后执行2
4.1 public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)
4.2 public <U> CompletableFuture<U> thenApply(Function<? super T,? extends U> fn);
<p>
5. thenAccept 没有返回结果,关心上一步的执行结果,上一步的执行结果会被当成参数,参数 T
5.1 public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)
5.2 public CompletableFuture<Void> thenAccept(Consumer<? super T> action)
<p>
6. thenCompose 有返回值,顺序执行,第一步的返回结果为thenCompose的参数,允许对2个CompletionStage流水线进行操作,第一个操作完成时,将第一个的结果作为第二个参数
public <U> CompletableFuture<U> thenCompose(Function<? super T, ? extends CompletionStage<U>> fn)
<p>
7.thenCombine
7.1 聚合and,有返回值  当
7.2 把两个任务都执行完毕后,会将两个结果都交给thenCombine去处理
7.3 thenAcceptBoth(没有返回值)与 thenCombine(有返回值)的区别
public <U,V> CompletableFuture<V> thenCombine( CompletionStage<? extends U> other, BiFunction<? super T,? super U,? extends V> fn)
<p>
8.thenAcceptBoth
8.1 聚合and
8.2 没有返回值  会把两个任务都执行完毕后,回将两个结果都交给thenAcceptBoth去处理
public <U> CompletableFuture<Void> thenAcceptBoth( CompletionStage<? extends U> other, BiConsumer<? super T, ? super U> action)
<p>
9.runAfterBoth
9.1 聚合and
9.2没有返回值,
9.3当有连个任务时,两个任务都执行完,在执行下一个任务
public CompletableFuture<Void> runAfterBoth(CompletionStage<?> other,Runnable action);
<p>
10. applyToEither
10.1 聚合 or
10.2 有返回值
10.2 针对2个CompletionStage,将计算速度最快的那个CompletionStage的结果作为下一步的处理
public <U> CompletableFuture<U> applyToEither(CompletionStage<? extends T> other, Function<? super T, U> fn);
<p>
11.exceptionally
11.1 异常处理
11.2 有返回值
简单理解 就是当程序执行错误进入exceptionally方法
public CompletableFuture<T> exceptionally( Function<Throwable, ? extends T> fn)
<p>
12.whenComplete
可以获取到上一次的返回结果
public CompletableFuture<T> whenComplete(BiConsumer<? super T, ? super Throwable> action)
<p>
13. handle
有返回值
相当于 try()finally() ,可以对执行结果进行处理,也可以对异常信息进行处理
 public <U> CompletableFuture<U> handle( BiFunction<? super T, Throwable, ? extends U> fn)
runAsync

1.public static CompletableFuture runAsync(Runnable runnable);

public static void main(String[] args) throws ExecutionException, InterruptedException {
    
    log.info("主线程start……");

    /**
     * 异步任务
     *  没有返回值,为定义线程池
     *  public static CompletableFuture<Void> runAsync(Runnable runnable);
     */
    CompletableFuture<Void> runAsync = CompletableFuture.runAsync(
            () -> {
                log.info("子线程future线程start……");
                int i = 10 / 2;
                log.info("线程名称:{},线程执行结果:{}", Thread.currentThread().getName(), i);
                log.info("子线程future线程end……");
            });

    // 调用异步任务
    runAsync.get();

    log.info("主线程end……");
}

2.public static CompletableFuture runAsync(Runnable runnable, Executor executor)

 public static void main(String[] args) throws ExecutionException, InterruptedException {
        AsyFutureDemo.runAsync();
    }

    /**
     * 线程池对象
     */
    public static ThreadPoolExecutor threadPool = new ThreadPoolExecutor(Runtime.getRuntime().availableProcessors(),
            Runtime.getRuntime().availableProcessors() + 1,
            3,
            TimeUnit.SECONDS,
            new LinkedBlockingQueue<Runnable>(3),
            Executors.defaultThreadFactory(),
            new ThreadPoolExecutor.CallerRunsPolicy());

    public static void runAsync() throws ExecutionException, InterruptedException {
        log.info("主线程start……");

        /**
         * 异步任务
         *  没有返回值,为定义线程池
         *  public static CompletableFuture<Void> runAsync(Runnable runnable);
         */
        CompletableFuture<Void> runAsync = CompletableFuture.runAsync(
                () -> {
                    log.info("子线程future线程start……");
                    int i = 10 / 2;
                    log.info("线程名称:{},线程执行结果:{}", Thread.currentThread().getName(), i);
                    log.info("子线程future线程end……");
                }, threadPool);

        // 调用异步任务
        runAsync.get();

        log.info("主线程end……");
    }
supplyAsync

public static CompletableFuture supplyAsync(Supplier supplier)

public static void supplyAsync() throws ExecutionException, InterruptedException {
    log.info("主线程start……");

    CompletableFuture<Integer> supplyAsync = CompletableFuture.supplyAsync(
            () -> {
                log.info("子线程future线程start……");
                int i = 10 / 2;
                log.info("线程名称:{},线程执行结果:{}", Thread.currentThread().getName(), i);
                log.info("子线程future线程end……");
                return i;
            });

    supplyAsync.get();

    log.info("主线程end……");
}

public static CompletableFuture supplyAsync(Supplier supplier, Executor executor)

public static void supplyAsync() throws ExecutionException, InterruptedException {
    log.info("主线程start……");

    CompletableFuture<Integer> supplyAsync = CompletableFuture.supplyAsync(
            () -> {
                log.info("子线程future线程start……");
                int i = 10 / 2;
                log.info("线程名称:{},线程执行结果:{}", Thread.currentThread().getName(), i);
                log.info("子线程future线程end……");
                return i;
            },threadPool);

    supplyAsync.get();

    log.info("主线程end……");
}

/**
 * 线程池对象
 */
public static ThreadPoolExecutor threadPool = new ThreadPoolExecutor(Runtime.getRuntime().availableProcessors(),
        Runtime.getRuntime().availableProcessors() + 1,
        3,
        TimeUnit.SECONDS,
        new LinkedBlockingQueue<Runnable>(3),
        Executors.defaultThreadFactory(),
        new ThreadPoolExecutor.CallerRunsPolicy());
thenRun
/**
 * 第一步执行完执行第二步,第二步的不关心第一执行的结果
 * <p>
 * 5. thenRun
 * 5.1 public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)
 * 5.2 public CompletableFuture<Void> thenRun(Runnable action)  不关心返回值,也不关心也行结果,只有顺序,1执行后
 */
public static void main(String[] args) throws Exception {
    // 1.public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)
    // 2.public CompletableFuture<Void> thenRun(Runnable action)  不关心返回值,也不关心也行结果,只有顺序,1执行后2才会执行
    CompletableFuture<Void> thenRun = CompletableFuture.supplyAsync(
            () -> {
                int i = 10 / 2;
                log.info("线程名称:{},线程执行结果:{}", Thread.currentThread().getName(), i);
                return i;
            }
    ).thenRun(
            () -> {
                log.info("上一步执行结束这一步才会执行,且不关心返回值,也不关心也行结果,只有顺序");
            }
    );
    // 异步调用执行
    thenRun.get();
    
}
thenApply
/**
 * 第一步执行完执行第二步,第二步的参数就是第一步返回的结果
 * <p>
 * 6. thenApply 有返回值U,也关心上一步的返回值,上一步的返回值会被当成参数,参数类型为T,也是顺序执行,1执行后执行2
 * 6.1 public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)
 * 6.2 public <U> CompletableFuture<U> thenApply(Function<? super T,? extends U> fn);
 */
public static void main(String[] args) throws Exception {
    // thenApply 有返回值U,也关心上一步的返回值,上一步的返回值会被当成参数,参数类型为T,也是顺序执行,1执行后执行2
    // 1.public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)
    // 2.public <U> CompletableFuture<U> thenApply(Function<? super T,? extends U> fn);
    CompletableFuture<Integer> thenApply = CompletableFuture.supplyAsync(
            () -> {
                int i = 10 / 2;
                log.info("线程名称:{},线程执行结果:{}", Thread.currentThread().getName(), i);
                return i;
            }
    ).thenApply((e) -> {
        return e + 2;
    });

    Integer e = thenApply.get();
    System.out.println("e = " + e);
}
thenAccept
/**
 *第一不执行完执行第二步,没有返回值,第一步的返回值为第二步的参数
 * supplyAsync  
 * 1 public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)
 * 2 public CompletableFuture<Void> thenAccept(Consumer<? super T> action)
 */
public static void main(String[] args) throws Exception {
    // thenAccept 没有返回结果,关心上一步的执行结果,上一步的执行结果会被当成参数,参数 T
    // 1.public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)
    // 2.public CompletableFuture<Void> thenAccept(Consumer<? super T> action)
    CompletableFuture<Void> thenAccept = CompletableFuture.supplyAsync(
            () -> {
                int i = 10 / 2;
                log.info("线程名称:{},线程执行结果:{}", Thread.currentThread().getName(), i);
                return i;
            }
    ).thenAccept(
            e -> {
                int k = e + 3;
                log.info("k的结果为{}", k);
            }
    );
    
    // 调用异步方法
    thenAccept.get();
}
thenCompose
/**
 * 1. 有返回值
 * 2. 顺序执行,第一步的返回结果为thenCompose的参数
 * 3. 允许对2个CompletionStage流水线进行操作,第一个操作完成时,将第一个的结果作为第二个参数
 * thenCompose
 * public <U> CompletableFuture<U> thenCompose(Function<? super T, ? extends CompletionStage<U>> fn)
 */
public static void main(String[] args) throws Exception {
    // thenCompose
    // public <U> CompletableFuture<U> thenCompose(Function<? super T, ? extends CompletionStage<U>> fn)
    // 第一次执行
    CompletableFuture<Integer> thenCompose = CompletableFuture.supplyAsync(
            () -> {
                int i = 10 / 2;
                log.info("线程名称:{},线程执行结果:{}", Thread.currentThread().getName(), i);
                return i;
            }).thenCompose(new Function<Integer, CompletionStage<Integer>>() {
        @Override
        public CompletionStage<Integer> apply(Integer i) {
            // 第二次执行
            CompletableFuture<Integer> supplyAsync = CompletableFuture.supplyAsync(
                    () -> {
                        int j = i + 2;
                        log.info("线程名称:{},线程执行结果:{}", Thread.currentThread().getName(), j);
                        return j;
                    });
            return supplyAsync;
        }
    });
    // 调用异步
    Integer integer = thenCompose.get();
    System.out.println("integer = " + integer);
}
thenCombine(and聚合)
/**
 * 1. 聚合and
 * 2. 有返回值  会把两个任务都执行完毕后,回将两个结果都交给thenCombine去处理
 * 3. thenAcceptBoth(没有返回值)与 thenCombine(有返回值)的区别
 * <p>
 * thenCombine
 * public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)
 * public <U,V> CompletableFuture<V> thenCombine( CompletionStage<? extends U> other, BiFunction<? super T,? super U,? extends V> fn)
 */
public static void main(String[] args) throws ExecutionException, InterruptedException {
    // 聚合and
    // 有返回值  会把两个任务都执行完毕后,回将两个结果都交给thenCombine去处理
    //  public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)
    //  public <U,V> CompletableFuture<V> thenCombine( CompletionStage<? extends U> other, BiFunction<? super T,? super U,? extends V> fn)
    // 第一个执行
    CompletableFuture<Integer> f1 = CompletableFuture.supplyAsync(() -> {
        int i = 10 / 2;
        return i;
    });
    // 第二个执行
    CompletableFuture<Integer> f2 = CompletableFuture.supplyAsync(() -> {
        int i = 10 / 3;
        return i;
    });
    // thenCombine 合并操作
    CompletableFuture<Integer> thenCombine = f1.thenCombine(f2, (x, y) -> {
        log.info("x为第一个执行结果:{}", x);
        log.info("y为第二个执行结果:{}", y);
        return x + y;
    });
    // 调用异步方法
    Integer integer = thenCombine.get();
    System.out.println("最终结果 = " + integer);
    
}
thenAcceptBoth(and聚合)
/**
 * 1. 聚合and
 * 2. 没有返回值  会把两个任务都执行完毕后,回将两个结果都交给thenAcceptBoth去处理
 * 3. thenAcceptBoth(没有返回值)与 thenCombine(有返回值)的区别
 * thenAcceptBoth
 * public <U> CompletableFuture<Void> thenAcceptBoth( CompletionStage<? extends U> other, BiConsumer<? super T, ? super U> action);
 */
public static void main(String[] args) throws Exception {
    // public <U> CompletableFuture<Void> thenAcceptBoth( CompletionStage<? extends U> other, BiConsumer<? super T, ? super U> action)
    // 第一个执行
    CompletableFuture<Integer> f1 = CompletableFuture.supplyAsync(() -> {
        int i = 10 / 2;
        return i;
    });
    // 第二个执行
    CompletableFuture<Integer> f2 = CompletableFuture.supplyAsync(() -> {
        int i = 10 / 3;
        return i;
    });
    // thenAcceptBoth 合并操作 ,没有返回值
    CompletableFuture<Void> acceptBoth = f1.thenAcceptBoth(f2, (x, y) -> {
        log.info("x为第一个执行结果:{}", x);
        log.info("y为第二个执行结果:{}", y);
    });
    // 调用异步方法
    acceptBoth.get();
}
runAfterBoth(and聚合)
/**
 * 9.runAfterBoth
 * 9.1 聚合and
 * 9.2没有返回值,
 * 9.3当有连个任务时,两个任务都执行完,在执行下一个任务
 * public CompletableFuture<Void> runAfterBoth(CompletionStage<?> other,Runnable action);
 */
public static void main(String[] args) throws ExecutionException, InterruptedException {
    
    //  public CompletableFuture<Void> runAfterBoth(CompletionStage<?> other,Runnable action);
    
    // 第一个执行
    CompletableFuture<Integer> f1 = CompletableFuture.supplyAsync(() -> {
        int i = 10 / 2;
        return i;
    });
    // 第二个执行
    CompletableFuture<Integer> f2 = CompletableFuture.supplyAsync(() -> {
        int i = 10 / 3;
        return i;
    });
    // thenAcceptBoth 合并操作 ,没有返回值
    CompletableFuture<Void> afterBoth = f1.runAfterBoth(f2, () -> {
        log.info("第一个和第二个执行完,接下来的业务");
    });
    // 调用异步方法
    afterBoth.get();
}
applyToEither(or聚合)
/**
 * 10. applyToEither
 * 10.1 聚合 or
 * 10.2 有返回值
 * 10.2 针对2个CompletionStage,将计算速度最快的那个CompletionStage的结果作为下一步的处理
 * public <U> CompletableFuture<U> applyToEither(CompletionStage<? extends T> other, Function<? super T, U> fn);
 */
public static void main(String[] args) throws ExecutionException, InterruptedException {
    // public <U> CompletableFuture<U> applyToEither(CompletionStage<? extends T> other, Function<? super T, U> fn);
    // 第一个执行
    CompletableFuture<Integer> f1 = CompletableFuture.supplyAsync(() -> {
        int i = 10 / 5;
        log.info("第一个执行结果{}",i);
        return i;
    });
    // 第二个执行
    CompletableFuture<Integer> f2 = CompletableFuture.supplyAsync(() -> {
        int i = 10 / 2;
        log.info("第二个执行结果{}",i);
        return i;
    });
    // 将计算速度最快的那个CompletionStage的结果进行处理
    CompletableFuture<Integer> applyToEither = f1.applyToEither(f2, res -> {
        int i = res + 5;
        return i;
    });
    Integer integer = applyToEither.get();
    System.out.println("integer = " + integer);
}
exceptionally(异常处理)
/**
 * 11.exceptionally
 * 11.1 异常处理
 * 11.2 有返回值
 * 简单理解 就是当程序执行错误进入exceptionally方法
 * public CompletableFuture<T> exceptionally( Function<Throwable, ? extends T> fn)
 *
 * @param args
 */
public static void main(String[] args) throws ExecutionException, InterruptedException {
    CompletableFuture<Integer> exceptionally = CompletableFuture.supplyAsync(() -> {
        int i = 10 / 0;
        return i;
    }).exceptionally(e -> {
        log.info("当执行抛出异常进入此方法,异常信息:{}", e.getMessage());
        return null;
    });
    Integer integer = exceptionally.get();
    System.out.println("integer = " + integer);
}
whenComplete(异常处理)
/**
 * 11.whenComplete
 * 可以获取到上一次的返回结果
 * public CompletableFuture<T> whenComplete(BiConsumer<? super T, ? super Throwable> action)
 */
public static void main(String[] args) throws ExecutionException, InterruptedException {
    //
    CompletableFuture<Integer> whenComplete = CompletableFuture.supplyAsync(() -> {
        int i = 10 / 5;
        return i;
    }).whenComplete((t, e) -> {
        log.info("上一步的执行结果{}", t);
        if (t > 0) {
            System.out.println("t 大于 0,结果为: " + t);
                       }
    });
    Integer integer = whenComplete.get();
    System.out.println("integer = " + integer);
}
handle(异常处理)
/**
 * 13. handle
 * 有返回值
 * 相当于 try()finally() ,可以对执行结果进行处理,也可以对异常信息进行处理
 * public <U> CompletableFuture<U> handle( BiFunction<? super T, Throwable, ? extends U> fn)
 */
public static void main(String[] args) throws ExecutionException, InterruptedException {
    //
    CompletableFuture<Integer> handle = CompletableFuture.supplyAsync(() -> {
        int i = 10 / 0;
        return i;
    }).handle((t, e) -> {
        log.info("上一步的执行结果{}", t);
        int res = 0;
        if (e != null) {
            log.info("异常信息{}", e.getMessage());
            return null;
        }
        if (t != null) {
            res = t + 1;
        }
        return res;
    });

    Integer integer = handle.get();
    System.out.println("integer = " + integer);
}

所有代码

import lombok.extern.slf4j.Slf4j;
import org.apache.tomcat.jni.User;

import java.util.concurrent.*;
import java.util.function.Function;

/**
 * 异步编排
 */
@Slf4j
public class AsyFutureDemo {


    /**
     * 1.runAsync 没有返回值
     * 2.1 public static CompletableFuture<Void> runAsync(Runnable runnable);  使用默认的线程池
     * 2.2 public static CompletableFuture<Void> runAsync(Runnable runnable,  Executor executor) 自定义线程池
     * <p>
     * 2.supplyAsync:    有返回值的,关注返回值
     * 2.1 public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier) 使用默认的线程池
     * 2.3 public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier,  Executor executor) 自定义线程池
     * <p>
     * 3. thenRun 第一步执行完执行第二步,第二步的不关心第一执行的结果
     * 3.1 public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)
     * 3.2 public CompletableFuture<Void> thenRun(Runnable action)  不关心返回值,也不关心也行结果,只有顺序,1执行后2才会执行
     * <p>
     * 4. thenApply 有返回值U,也关心上一步的返回值,上一步的返回值会被当成参数,参数类型为T,也是顺序执行,1执行后执行2
     * 4.1 public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)
     * 4.2 public <U> CompletableFuture<U> thenApply(Function<? super T,? extends U> fn);
     * <p>
     * 5. thenAccept 没有返回结果,关心上一步的执行结果,上一步的执行结果会被当成参数,参数 T
     * 5.1 public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)
     * 5.2 public CompletableFuture<Void> thenAccept(Consumer<? super T> action)
     * <p>
     * 6. thenCompose 有返回值,顺序执行,第一步的返回结果为thenCompose的参数,允许对2个CompletionStage流水线进行操作,第一个操作完成时,将第一个的结果作为第二个参数
     * public <U> CompletableFuture<U> thenCompose(Function<? super T, ? extends CompletionStage<U>> fn)
     * <p>
     * 7.thenCombine
     * 7.1 聚合and,有返回值  当
     * 7.2 把两个任务都执行完毕后,会将两个结果都交给thenCombine去处理
     * 7.3 thenAcceptBoth(没有返回值)与 thenCombine(有返回值)的区别
     * public <U,V> CompletableFuture<V> thenCombine( CompletionStage<? extends U> other, BiFunction<? super T,? super U,? extends V> fn)
     * <p>
     * 8.thenAcceptBoth
     * 8.1 聚合and
     * 8.2 没有返回值  会把两个任务都执行完毕后,回将两个结果都交给thenAcceptBoth去处理
     * public <U> CompletableFuture<Void> thenAcceptBoth( CompletionStage<? extends U> other, BiConsumer<? super T, ? super U> action)
     * <p>
     * 9.runAfterBoth
     * 9.1 聚合and
     * 9.2没有返回值,
     * 9.3当有连个任务时,两个任务都执行完,在执行下一个任务
     * public CompletableFuture<Void> runAfterBoth(CompletionStage<?> other,Runnable action);
     * <p>
     * 10. applyToEither
     * 10.1 聚合 or
     * 10.2 有返回值
     * 10.2 针对2个CompletionStage,将计算速度最快的那个CompletionStage的结果作为下一步的处理
     * public <U> CompletableFuture<U> applyToEither(CompletionStage<? extends T> other, Function<? super T, U> fn);
     * <p>
     * 11.exceptionally
     * 11.1 异常处理
     * 11.2 有返回值
     * 简单理解 就是当程序执行错误进入exceptionally方法
     * public CompletableFuture<T> exceptionally( Function<Throwable, ? extends T> fn)
     * <p>
     * 12.whenComplete
     * 可以获取到上一次的返回结果
     * public CompletableFuture<T> whenComplete(BiConsumer<? super T, ? super Throwable> action)
     * <p>
     * 13. handle
     * 有返回值
     * 相当于 try()finally() ,可以对执行结果进行处理,也可以对异常信息进行处理
     *  public <U> CompletableFuture<U> handle( BiFunction<? super T, Throwable, ? extends U> fn)
     */

    /**
     * 13. handle
     * 有返回值
     * 相当于 try()finally() ,可以对执行结果进行处理,也可以对异常信息进行处理
     * public <U> CompletableFuture<U> handle( BiFunction<? super T, Throwable, ? extends U> fn)
     */
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        //
        CompletableFuture<Integer> handle = CompletableFuture.supplyAsync(() -> {
            int i = 10 / 0;
            return i;
        }).handle((t, e) -> {
            log.info("上一步的执行结果{}", t);
            int res = 0;
            if (e != null) {
                log.info("异常信息{}", e.getMessage());
                return null;
            }
            if (t != null) {
                res = t + 1;
            }
            return res;
        });

        Integer integer = handle.get();
        System.out.println("integer = " + integer);
    }

    /**
     * 12.whenComplete
     * 可以获取到上一次的返回结果
     * public CompletableFuture<T> whenComplete(BiConsumer<? super T, ? super Throwable> action)
     */
    public static void whenComplete() throws ExecutionException, InterruptedException {

        //
        CompletableFuture<Integer> whenComplete = CompletableFuture.supplyAsync(() -> {
            int i = 10 / 5;
            return i;
        }).whenComplete((t, e) -> {
            log.info("上一步的执行结果{}", t);
            if (t > 0) {
                System.out.println("t 大于 0,结果为: " + t);
            }

        });

        Integer integer = whenComplete.get();
        System.out.println("integer = " + integer);


    }

    /**
     * 11.exceptionally
     * 11.1 异常处理
     * 11.2 有返回值
     * 简单理解 就是当程序执行错误进入exceptionally方法
     * public CompletableFuture<T> exceptionally( Function<Throwable, ? extends T> fn)
     */
    public static void exceptionally() throws ExecutionException, InterruptedException {
        CompletableFuture<Integer> exceptionally = CompletableFuture.supplyAsync(() -> {
            int i = 10 / 0;
            return i;
        }).exceptionally(e -> {
            log.info("当执行抛出异常进入此方法,异常信息:{}", e.getMessage());
            return null;
        });

        Integer integer = exceptionally.get();
        System.out.println("integer = " + integer);
    }

    /**
     * 10. applyToEither
     * 10.1 聚合 or
     * 10.2 有返回值
     * 10.2 针对2个CompletionStage,将计算速度最快的那个CompletionStage的结果作为下一步的处理
     * public <U> CompletableFuture<U> applyToEither(CompletionStage<? extends T> other, Function<? super T, U> fn);
     */
    public static void applyToEither() throws ExecutionException, InterruptedException {

        // public <U> CompletableFuture<U> applyToEither(CompletionStage<? extends T> other, Function<? super T, U> fn);

        // 第一个执行
        CompletableFuture<Integer> f1 = CompletableFuture.supplyAsync(() -> {
            int i = 10 / 5;
            log.info("第一个执行结果{}", i);
            return i;
        });

        // 第二个执行
        CompletableFuture<Integer> f2 = CompletableFuture.supplyAsync(() -> {
            int i = 10 / 2;
            log.info("第二个执行结果{}", i);
            return i;
        });

        // 将计算速度最快的那个CompletionStage的结果进行处理
        CompletableFuture<Integer> applyToEither = f1.applyToEither(f2, res -> {
            int i = res + 5;
            return i;
        });

        Integer integer = applyToEither.get();
        System.out.println("integer = " + integer);
    }


    /**
     * 9.runAfterBoth
     * 9.1 聚合and
     * 9.2没有返回值,
     * 9.3当有连个任务时,两个任务都执行完,在执行下一个任务
     * public CompletableFuture<Void> runAfterBoth(CompletionStage<?> other,Runnable action);
     */
    public static void runAfterBoth() throws ExecutionException, InterruptedException {

        //  public CompletableFuture<Void> runAfterBoth(CompletionStage<?> other,Runnable action);

        // 第一个执行
        CompletableFuture<Integer> f1 = CompletableFuture.supplyAsync(() -> {
            int i = 10 / 2;
            return i;
        });

        // 第二个执行
        CompletableFuture<Integer> f2 = CompletableFuture.supplyAsync(() -> {
            int i = 10 / 3;
            return i;
        });

        // thenAcceptBoth 合并操作 ,没有返回值
        CompletableFuture<Void> afterBoth = f1.runAfterBoth(f2, () -> {
            log.info("第一个和第二个执行完,接下来的业务");
        });

        // 调用异步方法
        afterBoth.get();
    }


    /**
     * 1. 聚合and
     * 2. 没有返回值  会把两个任务都执行完毕后,回将两个结果都交给thenAcceptBoth去处理
     * 3. thenAcceptBoth(没有返回值)与 thenCombine(有返回值)的区别
     * thenAcceptBoth
     * public <U> CompletableFuture<Void> thenAcceptBoth( CompletionStage<? extends U> other, BiConsumer<? super T, ? super U> action);
     */
    public static void thenAcceptBoth() throws Exception {

        // public <U> CompletableFuture<Void> thenAcceptBoth( CompletionStage<? extends U> other, BiConsumer<? super T, ? super U> action)

        // 第一个执行
        CompletableFuture<Integer> f1 = CompletableFuture.supplyAsync(() -> {
            int i = 10 / 2;
            return i;
        });

        // 第二个执行
        CompletableFuture<Integer> f2 = CompletableFuture.supplyAsync(() -> {
            int i = 10 / 3;
            return i;
        });

        // thenAcceptBoth 合并操作 ,没有返回值
        CompletableFuture<Void> acceptBoth = f1.thenAcceptBoth(f2, (x, y) -> {
            log.info("x为第一个执行结果:{}", x);
            log.info("y为第二个执行结果:{}", y);

        });

        // 调用异步方法
        acceptBoth.get();
    }


    /**
     * 1. 聚合and
     * 2. 有返回值  会把两个任务都执行完毕后,回将两个结果都交给thenCombine去处理
     * 3. thenAcceptBoth(没有返回值)与 thenCombine(有返回值)的区别
     * <p>
     * thenCombine
     * public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)
     * public <U,V> CompletableFuture<V> thenCombine( CompletionStage<? extends U> other, BiFunction<? super T,? super U,? extends V> fn)
     */
    public static void thenCombine() throws ExecutionException, InterruptedException {
        // 聚合and
        // 有返回值  会把两个任务都执行完毕后,回将两个结果都交给thenCombine去处理
        //  public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)
        //  public <U,V> CompletableFuture<V> thenCombine( CompletionStage<? extends U> other, BiFunction<? super T,? super U,? extends V> fn)

        // 第一个执行
        CompletableFuture<Integer> f1 = CompletableFuture.supplyAsync(() -> {
            int i = 10 / 2;
            return i;
        });

        // 第二个执行
        CompletableFuture<Integer> f2 = CompletableFuture.supplyAsync(() -> {
            int i = 10 / 3;
            return i;
        });

        // thenCombine 合并操作
        CompletableFuture<Integer> thenCombine = f1.thenCombine(f2, (x, y) -> {
            log.info("x为第一个执行结果:{}", x);
            log.info("y为第二个执行结果:{}", y);
            return x + y;
        });

        // 调用异步方法
        Integer integer = thenCombine.get();
        System.out.println("最终结果 = " + integer);

    }

    /**
     * 1. 有返回值
     * 2. 顺序执行,第一步的返回结果为thenCompose的参数
     * 3. 允许对2个CompletionStage流水线进行操作,第一个操作完成时,将第一个的结果作为第二个参数
     * thenCompose
     * public <U> CompletableFuture<U> thenCompose(Function<? super T, ? extends CompletionStage<U>> fn)
     */
    public static void thenCompose(String[] args) throws Exception {
        // thenCompose
        // public <U> CompletableFuture<U> thenCompose(Function<? super T, ? extends CompletionStage<U>> fn)

        // 第一次执行
        CompletableFuture<Integer> thenCompose = CompletableFuture.supplyAsync(
                () -> {
                    int i = 10 / 2;
                    log.info("线程名称:{},线程执行结果:{}", Thread.currentThread().getName(), i);
                    return i;
                }).thenCompose(new Function<Integer, CompletionStage<Integer>>() {
            @Override
            public CompletionStage<Integer> apply(Integer i) {
                // 第二次执行
                CompletableFuture<Integer> supplyAsync = CompletableFuture.supplyAsync(
                        () -> {
                            int j = i + 2;
                            log.info("线程名称:{},线程执行结果:{}", Thread.currentThread().getName(), j);
                            return j;
                        });
                return supplyAsync;
            }
        });

        // 调用异步
        Integer integer = thenCompose.get();
        System.out.println("integer = " + integer);
    }


    /**
     * 第一不执行完执行第二步,没有返回值,第一步的返回值为第二步的参数
     * 7. supplyAsync
     * 7.1 public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)
     * 7.2 public CompletableFuture<Void> thenAccept(Consumer<? super T> action)
     */
    public static void thenAccept(String[] args) throws Exception {
        // thenAccept 没有返回结果,关心上一步的执行结果,上一步的执行结果会被当成参数,参数 T
        // 1.public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)
        // 2.public CompletableFuture<Void> thenAccept(Consumer<? super T> action)
        CompletableFuture<Void> thenAccept = CompletableFuture.supplyAsync(
                () -> {
                    int i = 10 / 2;
                    log.info("线程名称:{},线程执行结果:{}", Thread.currentThread().getName(), i);
                    return i;
                }
        ).thenAccept(
                e -> {
                    int k = e + 3;
                    log.info("k的结果为{}", k);
                }
        );

        // 调用异步方法
        thenAccept.get();

    }


    /**
     * 第一步执行完执行第二步,第二步的参数就是第一步返回的结果
     * <p>
     * 6. thenApply 有返回值U,也关心上一步的返回值,上一步的返回值会被当成参数,参数类型为T,也是顺序执行,1执行后执行2
     * 6.1 public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)
     * 6.2 public <U> CompletableFuture<U> thenApply(Function<? super T,? extends U> fn);
     */
    public static void thenApply() throws Exception {
        // thenApply 有返回值U,也关心上一步的返回值,上一步的返回值会被当成参数,参数类型为T,也是顺序执行,1执行后执行2
        // 1.public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)
        // 2.public <U> CompletableFuture<U> thenApply(Function<? super T,? extends U> fn);
        CompletableFuture<Integer> thenApply = CompletableFuture.supplyAsync(
                () -> {
                    int i = 10 / 2;
                    log.info("线程名称:{},线程执行结果:{}", Thread.currentThread().getName(), i);
                    return i;
                }
        ).thenApply((e) -> {
            return e + 2;
        });

        Integer e = thenApply.get();
        System.out.println("e = " + e);
    }

    /**
     * 第一步执行完执行第二步,第二步的不关心第一执行的结果
     * <p>
     * 5. thenRun
     * 5.1 public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)
     * 5.2 public CompletableFuture<Void> thenRun(Runnable action)  不关心返回值,也不关心也行结果,只有顺序,1执行后2才会执行
     */
    public static void thenRun() throws Exception {
        // 1.public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)
        // 2.public CompletableFuture<Void> thenRun(Runnable action)  不关心返回值,也不关心也行结果,只有顺序,1执行后2才会执行
        CompletableFuture<Void> thenRun = CompletableFuture.supplyAsync(
                () -> {
                    int i = 10 / 2;
                    log.info("线程名称:{},线程执行结果:{}", Thread.currentThread().getName(), i);
                    return i;
                }
        ).thenRun(
                () -> {
                    log.info("上一步执行结束这一步才会执行,且不关心返回值,也不关心也行结果,只有顺序");
                }
        );

        // 异步调用执行
        thenRun.get();

    }

    /**
     * public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier) 使用默认的线程池
     * public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier,  Executor executor) 自定义线程池
     */
    public static void supplyAsync() throws ExecutionException, InterruptedException {
        log.info("主线程start……");

        CompletableFuture<Integer> supplyAsync = CompletableFuture.supplyAsync(
                () -> {
                    log.info("子线程future线程start……");
                    int i = 10 / 2;
                    log.info("线程名称:{},线程执行结果:{}", Thread.currentThread().getName(), i);
                    log.info("子线程future线程end……");
                    return i;
                }, threadPool);

        supplyAsync.get();

        log.info("主线程end……");
    }

    /**
     * 线程池对象
     */
    public static ThreadPoolExecutor threadPool = new ThreadPoolExecutor(Runtime.getRuntime().availableProcessors(),
            Runtime.getRuntime().availableProcessors() + 1,
            3,
            TimeUnit.SECONDS,
            new LinkedBlockingQueue<Runnable>(3),
            Executors.defaultThreadFactory(),
            new ThreadPoolExecutor.CallerRunsPolicy());

    /**
     * 1.public static CompletableFuture<Void> runAsync(Runnable runnable);  使用默认的线程池
     * 只需将 ,threadPool 去掉即可
     * 2.public static CompletableFuture<Void> runAsync(Runnable runnable,  Executor executor) 自定义线程池
     * 只需将 ,threadPool 加上即可
     */
    public static void runAsync() throws ExecutionException, InterruptedException {
        log.info("主线程start……");

        /**
         * 异步任务
         *  没有返回值,为定义线程池
         *  public static CompletableFuture<Void> runAsync(Runnable runnable);
         */
        CompletableFuture<Void> runAsync = CompletableFuture.runAsync(
                () -> {
                    log.info("子线程future线程start……");
                    int i = 10 / 2;
                    log.info("线程名称:{},线程执行结果:{}", Thread.currentThread().getName(), i);
                    log.info("子线程future线程end……");
                }, threadPool);

        // 调用异步任务
        runAsync.get();

        log.info("主线程end……");
    }

    /**
     * supplyAsync
     */


    /**
     * 异步调用
     *      异步调用实现一个不需要被等等的方法的返回值,让调用者继续执行(异步执行);
     *      在java 中,简单的讲就是开启另一个线程完成程序计算,使得调用者继续执行,不需要等等计算的结果,但是调用者任然需要获取线程的计算结果(不需要同步阻塞等待)。
     * 通俗理解就是:
     *      主线程将任务交个子线程,主线程就返回,不需要等待执行结果,主线程可以继续往下执行
     */

    /**
     * Future 也是一个异步计算结果返回接口,目的获取返回值结果。但是 future 在获取返回值结构的时候,方法必须同步阻塞等待返回值结果。
     *      Get : 获取结果(等待,阻塞)
     *      Get(timeout) : 获取结果,指定等待时间
     *      Cancel : 取消当前任务
     *      isDone : 判断任务是否已经完成 (轮询)
     * futrure 对于结果获取不是很方便,只能通过同步阻塞的方式获取结果,或者是轮询的方式获取到结果;阻塞的方式获取返回值结果与异步的思想想违背,轮询方式又很占用 cpu 资源,也不能及时得到我们结果。
     */

    /**
     * CompletableFuture
     *      可以帮助我们简化异步编程复杂性,提供了函数式编程的能力,可以通过回调函数的方式处理计算结果。
     * public class CompletableFuture<T> implements Future<T>, CompletionStage<T>
     *      CompletableFuture 具有Future 的特性,还实现了CompletionStage 接口,具备CompletionStage
     *      接口的特性: 串行执行,并行执行,聚合(AND 聚合,OR 聚合)
     * 1.串行关系执行
     *      then – 然后,也就是表示下一步,所以通常是一个串行的关系体现,then后面的单词(比如 run/apply/accept)就是函数是接口中抽象方法名称;
     *      利用上一步的执行结果,去进行下一步任务执行,任务执行具有先后顺序,因此把这种操作叫做串行关系
     *
     *      public CompletionStage<Void> thenRun(Runnable action);
     *      public CompletionStage<Void> thenRunAsync(Runnable action);
     *      public CompletableFuture<Void> thenRunAsync(Runnable action,Executor executor);
     *
     *      public <U> CompletableFuture<U> thenApply( Function<? super T,? extends U> fn) ;
     *      public <U> CompletionStage<U> thenApplyAsync(Function<? super T,? extends U> fn);
     *      public <U> CompletionStage<U> thenApplyAsync(Function<? super T,? extends U> fn,Executor executor);
     *
     *      public CompletionStage<Void> thenAccept(Consumer<? super T> action);
     *      public CompletionStage<Void> thenAcceptAsync(Consumer<? super T> action);
     *      public CompletionStage<Void> thenAcceptAsync(Consumer<? super T>  action, Executor executor);
     *
     *      public <U> CompletionStage<U> thenCompose(Function<? super T, ? extends CompletionStage<U>> fn);
     *      public <U> CompletionStage<U> thenComposeAsync(Function<? super T, ? extends CompletionStage<U>> fn);
     *      public <U> CompletionStage<U> thenComposeAsync(Function<? super T, ? extends CompletionStage<U>> fn, Executor executor);
     *
     * 2.聚合and
     * Combine…… with …… 和 both…… and …… 都是要求两者都必须满足,也就是and 且的关系。
     *
     *      public <U,V> CompletionStage<V> thenCombine  (CompletionStage<? extends U> other, BiFunction<? super T,? super U,? extends V> fn);
     *      public <U,V> CompletionStage<V> thenCombineAsync  (CompletionStage<? extends U> other,  BiFunction<? super T,? super U,? extends V> fn);
     *      public <U,V> CompletionStage<V> thenCombineAsync (CompletionStage<? extends U> other,  BiFunction<? super T,? super U,? extends V> fn, Executor executor);
     *
     *      public <U> CompletionStage<Void> thenAcceptBoth (CompletionStage<?  extends U> other, BiConsumer<? super T, ? super U> action);
     *      public <U> CompletionStage<Void> thenAcceptBothAsync (CompletionStage<? extends U> other, BiConsumer<? super T, ? super U> action);
     *      public <U> CompletionStage<Void> thenAcceptBothAsync(CompletionStage<? extends U> other, BiConsumer<? super T, ? super U> action,  Executor executor);
     *
     *      public CompletionStage<Void> runAfterBoth(CompletionStage<?> other, Runnable action);
     *      public CompletionStage<Void> runAfterBothAsync(CompletionStage<?> other, Runnable action);
     *      public CompletionStage<Void> runAfterBothAsync(CompletionStage<?> other, Runnable action, Executor executor);
     *
     * 3.聚合or
     *      public <U> CompletionStage<U> applyToEitherAsync (CompletionStage<? extends T> other, Function<? super T, U> fn);
     *      public <U> CompletionStage<U> applyToEitherAsync (CompletionStage<? extends T> other, Function<? super T, U> fn, Executor executor);
     *
     *      public <U> CompletionStage<U> applyToEitherAsync (CompletionStage<? extends T> other, Function<? super T, U> fn);
     *      public <U> CompletionStage<U> applyToEitherAsync (CompletionStage<? extends T> other, Function<? super T, U> fn, Executor executor);
     *      public CompletionStage<Void> acceptEither (CompletionStage<? extends T> other, Consumer<? super T> action);
     *
     *      public CompletionStage<Void> acceptEitherAsync (CompletionStage<? extends T> other, Consumer<? super T> action);
     *      public CompletionStage<Void> acceptEitherAsync (CompletionStage<? extends T> other, Consumer<? super T> action, Executor executor);
     *      public CompletionStage<Void> runAfterEither(CompletionStage<?> other, Runnable action);
     *      public CompletionStage<Void> runAfterEitherAsync (CompletionStage<?> other, Runnable action);
     *      public CompletionStage<Void> runAfterEitherAsync (CompletionStage<?> other, Runnable action, Executor executor);
     *
     * 4.异常处理
     *      public CompletionStage<T> exceptionally(Function<Throwable, ? extends T> fn);
     *      public CompletionStage<T> whenComplete (BiConsumer<? super T, ? super Throwable> action);
     *      public CompletionStage<T> whenCompleteAsync (BiConsumer<? super T, ? super Throwable> action);
     *      public CompletionStage<T> whenCompleteAsync (BiConsumer<? super T, ? super Throwable> action, Executor executor);
     *      public <U> CompletionStage<U> handle (BiFunction<? super T, Throwable, ? extends U> fn);
     *      public <U> CompletionStage<U> handleAsync (BiFunction<? super T, Throwable, ? extends U> fn);
     *      public <U> CompletionStage<U> handleAsync (BiFunction<? super T, Throwable, ? extends U> fn, Executor executor);
     *
     */

    /**
     * 异步开启
     *      CompletableFuture 提供了 4 个静态的方法,来创建一个异步操作(异步开启: 从这 4 个静态的方法开发即可)
     * 1.runAsync方法:
     *      没有返回值的方法,不关注返回值
     *      public static CompletableFuture<Void> runAsync(Runnable runnable);
     *      public static CompletableFuture<Void> runAsync(Runnable runnable,Executor executor);
     * 2.supplyAsync :
     *      有返回值,关注返回值的。
     *      public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier);
     *      public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier,Executor executor)
     */
}

网上找的参考Demo

	@Autowired
    private ThreadPoolExecutor executor;


 // 新建一个包装类对象
    SkuItemVo itemVo = new SkuItemVo();

    // 开启异步编排实现,提升服务性能  supplyAsync 有返回值
    // 1、根据 skuId 查询 sku 基本信息
    CompletableFuture<SkuInfoEntity> infoFuture =
            CompletableFuture.supplyAsync(() -> {
                SkuInfoEntity skuInfoEntity = this.getById(skuId);
                itemVo.setInfo(skuInfoEntity);
                return skuInfoEntity;
            }, executor);

    // 2、根据 skuId 查询 sku 图片信息(多个图片),skuId 是外键  runAsync 没有返回值
    CompletableFuture<Void> imagesFuture =
            CompletableFuture.runAsync(() -> {
                List<SkuImagesEntity> imageList =
                        skuImagesService.list(new
                                QueryWrapper<SkuImagesEntity>().eq("sku_id", skuId));
                itemVo.setImages(imageList);
            }, executor);

    //3、根据 spuID 获取 spu 的销售属性  (thenAcceptAsync 串行,没有返回值)
    CompletableFuture<Void> salesFuture =
            infoFuture.thenAcceptAsync((res) -> {
                // 获取 sku 与之对应的 spuId
                Long spuId = res.getSpuId();
                List<SkuItemSaleAttrVo> saleAttrVos =
                        skuSaleAttrValueService.getSaleAttrs(spuId);
                if (saleAttrVos.size() > 0 && saleAttrVos != null) {
                    itemVo.setAttrSales(saleAttrVos);
                }
            }, executor);

    //4、根据 spuId 查询 spu 的描述信息 (thenAcceptAsync 串行,没有返回值)
    CompletableFuture<Void> descFuture =
            infoFuture.thenAcceptAsync((res) -> {
                // 获取 sku 与之对应的 spuId
                Long spuId = res.getSpuId();
                SpuInfoDescEntity spuInfoDescEntity =
                        spuInfoDescService.getOne(new QueryWrapper<SpuInfoDescEntity>()
                                .eq("spu_id", spuId));
                if (spuInfoDescEntity != null) {
                    itemVo.setDesc(spuInfoDescEntity);
                }
            }, executor);

    //5、根据 spuID,categoryId 查询 sku 分组规格参数属性值 (thenAcceptAsync 串行,没有返回值)
    CompletableFuture<Void> groupFuture =
            infoFuture.thenAcceptAsync((res) -> {
                // 获取 sku 与之对应的 spuId
                Long spuId = res.getSpuId();
                // 获取分类 id
                Long categoryId = res.getCategoryId();
                List<SpuAttrGroupVo> attrGroupVos =
                        attrGroupService.getGroupAttr(spuId, categoryId);
                if (attrGroupVos.size() > 0) {
                    itemVo.setAttrGroups(attrGroupVos);
                }
            }, executor);

    // 等待所有的任务完成后,才能返回结果   
    try{
        CompletableFuture.allOf(infoFuture, imagesFuture, salesFuture, descFuture, groupFuture).get();
    catch (Exception e) {
        e.printStackTrace();
    }
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值