CompletableFuture异步编排

使用场景:一个接口需要查询五部分数据,a,b,c三部分数据直接没有关系,可以并行查询,但是,d,e数据需要等a数据查询结果返回才可以查询,如果使用普通的FutureTask可以实现,但是在项目中,我们不是直接new Thread的,需要使用线程池,所以 CompletableFuture,既可以异步编排,又可以使用线程池执行.

启动异步任务   runAsync supplyAsync

package com.buba.springbootdemo.thread;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 *
 */
public class Demo {

    public static void main(String[] args) throws Exception {

        ExecutorService executor = Executors.newFixedThreadPool(5);

        /**
         * 异步执行,无返回值
         * public static CompletableFuture<Void> runAsync(Runnable runnable)
         * public static CompletableFuture<Void> runAsync(Runnable runnable,Executor executor)
         */
        CompletableFuture<Void> future1 = CompletableFuture.runAsync(() -> System.out.println("线程执行"), executor);


        /**
         * 有返回值
         * public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)
         * public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier,Executor executor)
         */
        CompletableFuture<Integer> future2 = CompletableFuture.supplyAsync(() -> 1, executor);
        //返回1
        System.out.println(future2.get());
    }
}

完成回调与异常感知   whenComplete   exceptionally

public static void main(String[] args) throws Exception {

        ExecutorService executor = Executors.newFixedThreadPool(5);

        /**
         * whenComplete当前面的线程执行完后执行的操作,没有async的方法表示跟前面的线程用同一个线程执行,加async的方法表示使用新的线程执行
         * exceptionally,表示如果出现异常的话执行的方法,没有异常不会执行,并且它可以修改返回值,而whenComplete不可以修改返回值
         *
         * public CompletableFuture<T> whenComplete(BiConsumer<? super T, ? super Throwable> action)
         * public CompletableFuture<T> whenCompleteAsync(BiConsumer<? super T, ? super Throwable> action, Executor executor)
         * public CompletableFuture<T> exceptionally(Function<Throwable, ? extends T> fn)
         *
         * 返回的结果:null,异常信息:java.util.concurrent.CompletionException: java.lang.ArithmeticException: / by zero
         * java.util.concurrent.CompletionException: java.lang.ArithmeticException: / by zero
         * 10
         */
        CompletableFuture<Integer> future1 = CompletableFuture
                .supplyAsync(() -> 1/0, executor)
                .whenCompleteAsync((result,exception)-> System.out.println("返回的结果:"+result+",异常信息:"+exception),executor)
                .exceptionally((ex)->{
                    System.out.println(ex);
                    return 10;
                });
                
        System.out.println(future1.get());

    }

 完成回调与异常感知  handle 

    public static void main(String[] args) throws Exception {

        ExecutorService executor = Executors.newFixedThreadPool(5);

        /**
         *
         * handle方法跟whenComplete一样都是当之前的线程执行完再执行,但是它可以修改返回的结果
         *
         * public <U> CompletableFuture<U> handle(BiFunction<? super T, Throwable, ? extends U> fn)
         * public <U> CompletableFuture<U> handleAsync(BiFunction<? super T, Throwable, ? extends U> fn)
         * public <U> CompletableFuture<U> handleAsync(BiFunction<? super T, Throwable, ? extends U> fn, Executor executor)
         *
         * 返回结果:1,异常信息:null
         * 2
         */
        CompletableFuture<Integer> future2 = CompletableFuture
                .supplyAsync(() -> 1, executor)
                .handleAsync((result,exception)->{
                    System.out.println("返回结果:"+result+",异常信息:"+exception);
                    return 2;
                },executor);
                

        System.out.println(future2.get());
    }

线程串行化   thenRun,thenAccept,thenApply

    public static void main(String[] args) throws Exception {

        ExecutorService executor = Executors.newFixedThreadPool(5);


        /**
         * thenRun等之前线程执行完再执行,获取不到之前线程返回结果,自己当前线程也没有返回结果
         * public CompletableFuture<Void> thenRun(Runnable action)
         * public CompletableFuture<Void> thenRunAsync(Runnable action)
         * public CompletableFuture<Void> thenRunAsync(Runnable action,Executor executor)
         */
        CompletableFuture<Void> future1 = CompletableFuture
                .supplyAsync(() -> 1, executor)
                .thenRunAsync(() -> System.out.println("后续线程执行"), executor);

        /**
         * thenAccept等之前线程执行完再执行,能获取到之前线程返回结果,自己当前线程没有返回结果
         * public CompletableFuture<Void> thenAccept(Consumer<? super T> action)
         * public CompletableFuture<Void> thenAcceptAsync(Consumer<? super T> action)
         * public CompletableFuture<Void> thenAcceptAsync(Consumer<? super T> action,Executor executor)
         */
        CompletableFuture<Void> future2 = CompletableFuture
                .supplyAsync(() -> 1, executor)
                .thenAcceptAsync((result) -> System.out.println("后续线程执行,前面线程执行结果:" + result), executor);

        /**
         * thenApply等之前线程执行完再执行,能获取到之前线程返回结果,自己当前线程有返回结果
         * public <U> CompletableFuture<U> thenApply(Function<? super T,? extends U> fn)
         * public <U> CompletableFuture<U> thenApplyAsync(Function<? super T,? extends U> fn)
         * public <U> CompletableFuture<U> thenApplyAsync(Function<? super T,? extends U> fn, Executor executor)
         */
        CompletableFuture<Integer> future3 = CompletableFuture
                .supplyAsync(() -> 1, executor)
                .thenApplyAsync((result) -> {
                    System.out.println("后续线程执行,前面线程执行结果:" + result);
                    return 2;
                }, executor);

        System.out.println(future3.get());

        /**
         * 后续线程执行
         * 后续线程执行,前面线程执行结果:1
         * 后续线程执行,前面线程执行结果:1
         * 2
         */
    }

两任务组合-都要完成  thenCombineAsync ,runAfterBothAsync ,thenAcceptBothAsync

    public static void main(String[] args) throws Exception {

        ExecutorService executor = Executors.newFixedThreadPool(5);


        CompletableFuture future1 = CompletableFuture
                .supplyAsync(() -> {
                    System.out.println("第一个线程执行完了");
                    return 1;
                }, executor);

        /**
         *
         * runAfterBoth等前面两个线程都执行完,再执行的操作,获取不到前面的返回结果,但自己无返回结果
         * thenAcceptBoth等前面两个线程都执行完,再执行的操作,可以获取到前面的返回结果,但自己无返回结果
         * thenCombine等前面两个线程都执行完,再执行的操作,可以获取到前面的返回结果,自己有返回结果
         */
        CompletableFuture
                .runAsync(() -> {
                    try {
                        Thread.sleep(3000);
                        System.out.println("第二个线程执行完了");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }, executor)
                .runAfterBothAsync(future1, () -> System.out.println("前面两个都执行完了执行的"), executor);

        CompletableFuture
                .supplyAsync(() -> {
                    try {
                        Thread.sleep(3000);
                        System.out.println("第二个线程执行完了");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    return 2;
                }, executor)
                .thenAcceptBothAsync(future1, (result1,result2) -> System.out.println("前面两个都执行完了执行的,返回结果1:"+result1+",返回结果2:"+result2), executor);

        CompletableFuture future3 = CompletableFuture
                .supplyAsync(() -> {
                    try {
                        Thread.sleep(3000);
                        System.out.println("第二个线程执行完了");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    return 2;
                }, executor)
                .thenCombineAsync(future1, (result1, result2) -> {
                    System.out.println("前面两个都执行完了执行的,返回结果1:" + result1 + ",返回结果2:" + result2);
                    return 3;
                }, executor);

        System.out.println(future3.get());
    }

两任务组合有一个完成  runAfterEitherAsync,acceptEitherAsync,applyToEitherAsync

    public static void main(String[] args) throws Exception {

        ExecutorService executor = Executors.newFixedThreadPool(5);


        CompletableFuture future1 = CompletableFuture
                .supplyAsync(() -> {
                    try {
                        Thread.sleep(5000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("第一个线程执行完了");
                    return 1;
                }, executor);

        /**
         *
         * runAfterEitherAsync等前面两个线程中其中一个执行完,再执行的操作,获取不到前面的返回结果,但自己无返回结果
         * acceptEitherAsync等前面两个线程中其中一个执行完,再执行的操作,可以获取到前面的返回结果,但自己无返回结果
         * applyToEitherAsync等前面两个线程中其中一个执行完,再执行的操作,可以获取到前面的返回结果,自己有返回结果
         */
        CompletableFuture
                .runAsync(() -> {
                    try {
                        Thread.sleep(3000);
                        System.out.println("第二个线程执行完了");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }, executor)
                .runAfterEitherAsync(future1, () -> System.out.println("前面两个都执行完了执行的"), executor);

        CompletableFuture
                .supplyAsync(() -> {
                    try {
                        Thread.sleep(3000);
                        System.out.println("第二个线程执行完了");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    return 2;
                }, executor)
                .acceptEitherAsync(future1, (result1) -> System.out.println("前面两个都执行完了执行的,返回结果1:"+result1), executor);

        CompletableFuture future3 = CompletableFuture
                .supplyAsync(() -> {
                    try {
                        Thread.sleep(3000);
                        System.out.println("第二个线程执行完了");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    return 2;
                }, executor)
                .applyToEitherAsync(future1, (result1) -> {
                    System.out.println("前面两个都执行完了执行的,返回结果1:" + result1);
                    return 3;
                }, executor);

        System.out.println(future3.get());
    }

多任务组合 allOf,anyOf

    public static void main(String[] args) throws Exception {

        ExecutorService executor = Executors.newFixedThreadPool(5);
        
        CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> {
            System.out.println("线程1执行");
            return "线程1";
        }, executor);
        CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> {
            System.out.println("线程2执行");
            return "线程2";
        }, executor);
        CompletableFuture<String> future3 = CompletableFuture.supplyAsync(() -> {
            System.out.println("线程3执行");
            return "线程3";
        }, executor);

        /**
         * allOf等待所有的Future执行完毕
         * anyOf有一个执行完毕就会接着往下走
         */
        CompletableFuture<Void> allOf = CompletableFuture.allOf(future1, future2, future3);
        //得调用get方法进行阻塞
        allOf.get();

        CompletableFuture<Object> anyOf = CompletableFuture.anyOf(future1, future2, future3);

        System.out.println(anyOf.get());

    }

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值