CompletableFuture实现了对任务编排的能力,可以轻松地组织不同任务的运行顺序、规则以及方式

CompletableFuture是对Future的扩展和增强。CompletableFuture实现了Future接口,并在此基础上进行了丰富的扩展,完美弥补了Future的局限性,同时CompletableFuture实现了对任务编排的能力。借助这项能力,可以轻松地组织不同任务的运行顺序、规则以及方式。从某种程度上说,这项能力是它的核心能力。而在以往,虽然通过CountDownLatch等工具类也可以实现任务的编排,但需要复杂的逻辑处理,不仅耗费精力且难以维护。

CompletableFuture的继承结构如下:
在这里插入图片描述
CompletionStage接口定义了任务编排的方法,执行某一阶段,可以向下执行后续阶段。异步执行的,默认线程池是ForkJoinPool.commonPool(),但为了业务之间互不影响,且便于定位问题,强烈推荐使用自定义线程池。

CompletableFuture中默认线程池如下:

    private static final boolean useCommonPool =
        (ForkJoinPool.getCommonPoolParallelism() > 1);
     /**
     * Returns the targeted parallelism level of the common pool.
     */
    public static int getCommonPoolParallelism() {
	    /**
	     * Common pool parallelism. To allow simpler use and management
	     * when common pool threads are disabled, we allow the underlying
	     * common.parallelism field to be zero, but in that case still report
	     * parallelism as 1 to reflect resulting caller-runs mechanics.
	     */
        return commonParallelism;
    }

    /**
     * Default executor -- ForkJoinPool.commonPool() unless it cannot support parallelism.
     */
    private static final Executor asyncPool = useCommonPool ?
        ForkJoinPool.commonPool() : new ThreadPerTaskExecutor();

1 结果处理

public class CompletableFutureTest {
    static ThreadPoolExecutor executor = new ThreadPoolExecutor(5,
            50,
            10,
            TimeUnit.SECONDS,
            new LinkedBlockingQueue<>(100),
            Executors.defaultThreadFactory(),
            new ThreadPoolExecutor.AbortPolicy());

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        System.out.println("main start ...");
//        runAsync();
//        getIntegerCompletableFuture();
//        getIntegerCompletableFuture_2();
//        getIntegerCompletableFuture_3();
//        runAsync_2();
//        getIntegerCompletableFuture_4();
        getIntegerCompletableFuture_5();

        System.out.println("main end ...");
    }
}

异步发出请求,supplyAsync 会有接口的返回,future.get() 会阻塞等待结果的执行完毕。

    public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier,
                                                       Executor executor) {
        return asyncSupplyStage(screenExecutor(executor), supplier);
    }
    private static void getIntegerCompletableFuture() throws ExecutionException, InterruptedException {
        CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
            System.out.println(Thread.currentThread().getName() + " start ...");
            try {
                // 模拟执行任务 。。。
                TimeUnit.SECONDS.sleep(10);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            return 10;
        }, executor);
        System.out.println(future.get());
        /**
         * 情况1、future.get() 注释掉
         * main start ...
         * main end ...
         * pool-1-thread-1 start ...
         *
         * 情况2、future.get() 存在
         * main start ...
         * pool-1-thread-1 start ...
         * 10
         * main end ...
         */
    }

1 结果处理-whenCompleteAsync

当CompletableFuture的计算结果完成,或者抛出异常的时候,我们可以执行特定的 Action。主要是下面的方法:

    public CompletableFuture<T> whenCompleteAsync(
        BiConsumer<? super T, ? super Throwable> action, Executor executor) {
        return uniWhenCompleteStage(screenExecutor(executor), action);
    }
    private static void getIntegerCompletableFuture_2() throws ExecutionException, InterruptedException {
        CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
            System.out.println(Thread.currentThread().getName() + " start ...");
            int a = 1 / 0;
            return 10;
            /**
             * public CompletableFuture<T> whenCompleteAsync(
             *         BiConsumer<? super T, ? super Throwable> action, Executor executor){}
             */
        }, executor).whenCompleteAsync((t, u) -> {
            System.out.println("whenCompleteAsync start ...");
            System.out.println("t = " + t);
            System.out.println("u = " + u);
        }, executor);
        System.out.println(future.get());
        /**
         * int a = 1 / 0; 不存在
         * main start ...
         * pool-1-thread-1 start ...
         * whenCompleteAsync start ...
         * t = 10
         * u = null
         * 10
         * main end ...
         */

        /**
         * int a = 1 / 0; 存在
         * main start ...
         * pool-1-thread-1 start ...
         * whenCompleteAsync start ...
         * t = null                        特别注意:*********为null
         * u = java.util.concurrent.CompletionException: java.lang.ArithmeticException: / by zero
         * Exception in thread "main" java.util.concurrent.ExecutionException: java.lang.ArithmeticException: / by zero
         * 	at java.util.concurrent.CompletableFuture.reportGet(CompletableFuture.java:357)
         * 	at java.util.concurrent.CompletableFuture.get(CompletableFuture.java:1895)
         * 	at com.thread.future.CompletableFuture学习.CompletableFutureTest.getIntegerCompletableFuture_2(CompletableFutureTest.java:72)
         * 	at com.thread.future.CompletableFuture学习.CompletableFutureTest.main(CompletableFutureTest.java:25)
         * Caused by: java.lang.ArithmeticException: / by zero
         * 	at com.thread.future.CompletableFuture学习.CompletableFutureTest.lambda$getIntegerCompletableFuture_2$1(CompletableFutureTest.java:65)
         * 	at java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1590)
         * 	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
         * 	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
         * 	at java.lang.Thread.run(Thread.java:748)
         */

    }
    private static void runAsync() {
        CompletableFuture.runAsync(() -> {
            System.out.println(Thread.currentThread().getName() + " start ...");
            /**
             * public CompletableFuture<T> whenCompleteAsync(
             *         BiConsumer<? super T, ? super Throwable> action, Executor executor){}
             */
        }, executor).whenCompleteAsync((t, u) -> {
            System.out.println("whenCompleteAsync start ...");
            System.out.println("t = " + t);
            System.out.println("u = " + u);
        }, executor);
        /**
         * main start ...
         * pool-1-thread-1 start ...
         * main end ...
         * whenCompleteAsync start ...
         * t = null
         * u = null
         */
    }

2 结果处理-exceptionally

返回一个新的CompletableFuture,当前面的CompletableFuture完成时,它也完成;当它异常完成时,给定函数的异常触发这个CompletableFuture的完成。

    private static void getIntegerCompletableFuture_3() throws ExecutionException, InterruptedException {
        CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
            System.out.println(Thread.currentThread().getName() + " start ...");
            int a = 1 / 0;
            return 10;
        }, executor).whenCompleteAsync((t, u) -> {
            System.out.println("whenCompleteAsync start ...");
            System.out.println("t = " + t);
            System.out.println("u = " + u);
            /**
             * public CompletableFuture<T> exceptionally(
             *         Function<Throwable, ? extends T> fn) {}
             */
        }, executor).exceptionally(ex -> {
            System.out.println("ex = " + ex);
            return 100;
        });
        System.out.println(future.get());
        /**
         * main start ...
         * pool-1-thread-1 start ...
         * whenCompleteAsync start ...
         * t = null
         * u = java.util.concurrent.CompletionException: java.lang.ArithmeticException: / by zero
         * ex = java.util.concurrent.CompletionException: java.lang.ArithmeticException: / by zero
         * 100
         * main end ...
         */
    }

3 handleAsync

    private static void getIntegerCompletableFuture_4() throws ExecutionException, InterruptedException {
        CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
            System.out.println(Thread.currentThread().getName() + " start ...");
            int a = 1 / 0;
            return 10;
        }, executor).handleAsync((res, ex) -> {
            System.out.println("res = " + res);
            System.out.println("ex = " + ex);
            return 100;
        });
        System.out.println(future.get());
        /**
         * main start ...
         * pool-1-thread-1 start ...
         * res = null
         * ex = java.util.concurrent.CompletionException: java.lang.ArithmeticException: / by zero
         * 100
         * main end ...
         */
    }
    private static void getIntegerCompletableFuture_5() throws ExecutionException, InterruptedException {
        CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
            System.out.println(Thread.currentThread().getName() + " start ...");
            return 10;
        }, executor).handleAsync((res, ex) -> {
            System.out.println("res = " + res);
            System.out.println("ex = " + ex);
            if (Objects.nonNull(ex)) {
                return 100;
            }
            return res;
        });
        System.out.println(future.get());
        /**
         * main start ...
         * pool-1-thread-1 start ...
         * res = 10
         * ex = null
         * 10
         * main end ...
         */
    }
    private static void runAsync_2() {
        CompletableFuture.runAsync(() -> {
            System.out.println(Thread.currentThread().getName() + " start ...");
            /**
             * public <U> CompletionStage<U> handleAsync
             *         (BiFunction<? super T, Throwable, ? extends U> fn,
             *          Executor executor);
             */
        }, executor).handleAsync((res, ex) -> {
            System.out.println("res = " + res);
            System.out.println("ex = " + ex);
            return null;
        }, executor);
        /**
         * main start ...
         * pool-1-thread-1 start ...
         * main end ...
         * res = null
         * ex = null
         */
    }

2 对线程任务结果的一种消费函数

public class CompletableFuture串行Test {
    static ThreadPoolExecutor executor = new ThreadPoolExecutor(5,
            50,
            10,
            TimeUnit.SECONDS,
            new LinkedBlockingQueue<>(100),
            Executors.defaultThreadFactory(),
            new ThreadPoolExecutor.AbortPolicy());

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        System.out.println("main start ...");
//        runAsync_1();
//        runAsync_2();
//        supplyAsync();
        supplyAsync_2();
        System.out.println("main end ...");

    }
}

1 thenRunAsync

thenRun也是对线程任务结果的一种消费函数,与thenAccept不同的是,thenRun会在上一阶段 CompletableFuture计算完成的时候执行一个Runnable,而Runnable并不使用该CompletableFuture计算的结果。

    private static void runAsync_1() {
        CompletableFuture.runAsync(() -> {
                    System.out.println(Thread.currentThread().getName() + " start ...");
                    try {
                        TimeUnit.SECONDS.sleep(3);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
                /**
                 * public CompletionStage<Void> thenRunAsync(Runnable action, Executor executor);
                 */
                , executor).thenRunAsync(() -> System.out.println(Thread.currentThread().getName() + " start ..."), executor);
        /**
         * main start ...
         * pool-1-thread-1 start ...
         * main end ...
         * pool-1-thread-2 start ... (等待了3s)
         */
    }

2 thenAcceptAsync

thenRun也是对线程任务结果的一种消费函数,与thenAccept不同的是,thenRun会在上一阶段 CompletableFuture计算完成的时候执行一个Consumer,而Consumer使用该CompletableFuture计算的结果。观察该系列函数的参数类型可知,它们是函数式接口Consumer,这个接口只有输入,没有返回值。

    private static void runAsync_2() {
        CompletableFuture.runAsync(() -> {
                    System.out.println(Thread.currentThread().getName() + " start ...");
                    try {
                        TimeUnit.SECONDS.sleep(3);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
                /**
                 * public CompletionStage<Void> thenAcceptAsync(Consumer<? super T> action, Executor executor);
                 */
                , executor).thenAcceptAsync(t -> {
            System.out.println("t = " + t);
            System.out.println(Thread.currentThread().getName() + " start ...");
        }, executor);
        /**
         * main start ...
         * pool-1-thread-1 start ...
         * main end ...
         * t = null
         * pool-1-thread-2 start ...
         */
    }

    private static void supplyAsync() throws ExecutionException, InterruptedException {
        CompletableFuture<Void> future = CompletableFuture.supplyAsync(() -> {
            System.out.println(Thread.currentThread().getName() + " start ...");
            return 10;
            /**
             * public CompletionStage<Void> thenAcceptAsync(Consumer<? super T> action,
             *                                                  Executor executor);
             */
        }, executor).thenAcceptAsync(t -> {
            System.out.println("t = " + t);
        }, executor);
        System.out.println(future.get());
        /**
         * main start ...
         * pool-1-thread-1 start ...
         * t = 10
         * null
         * main end ...
         */
    }
    private static void supplyAsync_2() throws ExecutionException, InterruptedException {
        CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
            System.out.println(Thread.currentThread().getName() + " start ...");
            return 10;
            /**
             * public <U> CompletionStage<U> thenApplyAsync
             *         (Function<? super T,? extends U> fn,
             *          Executor executor);
             */
        }, executor).thenApplyAsync(t -> {
            System.out.println("t = " + t);
            return t * 100;
        }, executor);
        System.out.println(future.get());
        /**
         * main start ...
         * pool-1-thread-1 start ...
         * t = 10
         * 1000
         * main end ...
         */

    }

3 任务交互-完成一个

线程交互指将两个线程任务获取结果的速度相比较,按一定的规则进行下一步处理。

public class CompletableFuture只完成一个任务Test {
    static ThreadPoolExecutor executor = new ThreadPoolExecutor(5,
            50,
            10,
            TimeUnit.SECONDS,
            new LinkedBlockingQueue<>(100),
            Executors.defaultThreadFactory(),
            new ThreadPoolExecutor.AbortPolicy());

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        System.out.println("main start ...");
        CompletableFuture<Integer> future_1 = CompletableFuture.supplyAsync(() -> {
            System.out.println(Thread.currentThread().getName() + " future_1-start ...");
            try {
                TimeUnit.SECONDS.sleep(3);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println(Thread.currentThread().getName() + " future_1-end ...");
            return 66;
        }, executor);

        CompletableFuture<Integer> future_2 = CompletableFuture.supplyAsync(() -> {
            System.out.println(Thread.currentThread().getName() + " future_2-start ...");
            try {
                TimeUnit.SECONDS.sleep(10);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println(Thread.currentThread().getName() + " future_2-end ...");
            return 77;
        }, executor);

//        runAfterEitherAsync(future_1, future_2);
//        runAfterEitherAsync_2(future_1, future_2);
        runAfterEitherAsync_3(future_1, future_2);
    }
}

1 runAfterEitherAsync

两个线程任务相比较,有任何一个执行完成,就进行下一步操作,不关心运行结果。

    private static void runAfterEitherAsync(CompletableFuture<Integer> future_1, CompletableFuture<Integer> future_2) {
        /**
         * public CompletionStage<Void> runAfterEitherAsync
         *         (CompletionStage<?> other,
         *          Runnable action,
         *          Executor executor);
         */
        CompletableFuture<Void> voidCompletableFuture = future_1.runAfterEitherAsync(future_2, () -> {
            System.out.println(Thread.currentThread().getName() + " runAfterEitherAsync-start ...");
        }, executor);
        System.out.println("main end ...");
        /**
         * main start ...
         * pool-1-thread-1 future_1-start ...
         * pool-1-thread-2 future_2-start ...
         * main end ...
         * pool-1-thread-1 future_1-end ...
         * pool-1-thread-3 runAfterEitherAsync-start ...
         * pool-1-thread-2 future_2-end ...
         */
    }

2 acceptEitherAsync

两个线程任务相比较,先获得执行结果的,就对该结果进行下一步的消费操作。

    private static void runAfterEitherAsync_2(CompletableFuture<Integer> future_1, CompletableFuture<Integer> future_2) {
        /**
         * public CompletionStage<Void> acceptEitherAsync
         *         (CompletionStage<? extends T> other,
         *          Consumer<? super T> action,
         *          Executor executor);
         */
        future_1.acceptEitherAsync(future_2, f1 -> {
            System.out.println("f1 = " + f1);
        }, executor);
        System.out.println("main end ...");
        /**
         * main start ...
         * pool-1-thread-1 future_1-start ...
         * pool-1-thread-2 future_2-start ...
         * main end ...
         * pool-1-thread-1 future_1-end ...
         * f1 = 66
         * pool-1-thread-2 future_2-end ...
         */
    }

3 applyToEitherAsync

两个线程任务相比较,先获得执行结果的,就对该结果进行下一步的转化操作。

    private static void runAfterEitherAsync_3(CompletableFuture<Integer> future_1, CompletableFuture<Integer> future_2) throws ExecutionException, InterruptedException {
        /**
         * public <U> CompletableFuture<U> applyToEitherAsync(
         *         CompletionStage<? extends T> other, Function<? super T, U> fn,
         *         Executor executor) {}
         */
        CompletableFuture<Integer> future = future_1.applyToEitherAsync(future_2, f1 -> {
            Integer f3 = f1 * 1000;
            System.out.println("f3 = " + f3);
            return f3;
        }, executor);
        System.out.println(future.get());
        System.out.println("main end ...");
        /**
         * main start ...
         * pool-1-thread-1 future_1-start ...
         * pool-1-thread-2 future_2-start ...
         * pool-1-thread-1 future_1-end ...
         * f3 = 66000
         * 66000
         * main end ...
         * pool-1-thread-2 future_2-end ...
         */
    }

4 任务交互-都完成

public class CompletableFuture任务都完成Test {
    static ThreadPoolExecutor executor = new ThreadPoolExecutor(5,
            50,
            10,
            TimeUnit.SECONDS,
            new LinkedBlockingQueue<>(100),
            Executors.defaultThreadFactory(),
            new ThreadPoolExecutor.AbortPolicy());

    public static void main(String[] args) {
        System.out.println("main start ...");
        CompletableFuture<Integer> future_1 = CompletableFuture.supplyAsync(() -> {
            System.out.println(Thread.currentThread().getName() + " future_1-start ...");
            try {
                TimeUnit.SECONDS.sleep(3);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println(Thread.currentThread().getName() + " future_1-end ...");
            return 66;
        }, executor);

        CompletableFuture<Integer> future_2 = CompletableFuture.supplyAsync(() -> {
            System.out.println(Thread.currentThread().getName() + " future_2-start ...");
            try {
                TimeUnit.SECONDS.sleep(3);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println(Thread.currentThread().getName() + " future_2-end ...");
            return 77;
        }, executor);

//        runAfterBothAsync(future_1, future_2);
//        runAfterBothAsync_1(future_1, future_2);
        runAfterBothAsync_2(future_1, future_2);
    }
}

1 runAfterBothAsync

    private static void runAfterBothAsync(CompletableFuture<Integer> future_1, CompletableFuture<Integer> future_2) {
        /**
         * public CompletableFuture<Void> runAfterBoth(CompletionStage<?> other,
         *                                                 Runnable action){}
         */
        future_1.runAfterBothAsync(future_2, () -> {
            System.out.println(Thread.currentThread().getName() + " runAfterBothAsync-start ...");
        }, executor);
        System.out.println("main end ...");
        /**
         * main start ...
         * pool-1-thread-1 future_1-start ...
         * pool-1-thread-2 future_2-start ...
         * main end ...
         * pool-1-thread-2 future_2-end ...
         * pool-1-thread-1 future_1-end ...
         * (最后执行 。。。)
         * pool-1-thread-3 runAfterBothAsync-start ...
         */
    }

2 thenAcceptBothAsync

thenAcceptBoth函数的作用是,当两个CompletionStage都正常完成计算的时候,就会执行提供的action消费两个异步的结果。

    private static void runAfterBothAsync_1(CompletableFuture<Integer> future_1, CompletableFuture<Integer> future_2) {
        /**
         * public <U> CompletionStage<Void> thenAcceptBothAsync
         *         (CompletionStage<? extends U> other,
         *          BiConsumer<? super T, ? super U> action,
         *          Executor executor);
         */
        future_1.thenAcceptBothAsync(future_2, (f1, f2) -> {
            System.out.println("f1 = " + f1);
            System.out.println("f2 = " + f2);
        }, executor);
        System.out.println("main end ...");
        /**
         * main start ...
         * pool-1-thread-1 future_1-start ...
         * pool-1-thread-2 future_2-start ...
         * main end ...
         * pool-1-thread-2 future_2-end ...
         * pool-1-thread-1 future_1-end ...
         * f1 = 66
         * f2 = 77
         */
    }

3 thenCombineAsync

合并两个线程任务的结果,并进一步处理。

    private static void runAfterBothAsync_2(CompletableFuture<Integer> future_1, CompletableFuture<Integer> future_2) {
        /**
         * public <U,V> CompletionStage<V> thenCombineAsync
         *         (CompletionStage<? extends U> other,
         *          BiFunction<? super T,? super U,? extends V> fn,
         *          Executor executor);
         */
        future_1.thenCombineAsync(future_2, (f1, f2) -> {
            Integer f3 = f1 + f2;
            System.out.println("f3 = " + f3);
            return f3;
        }, executor);
        System.out.println("main end ...");
        /**
         * main start ...
         * pool-1-thread-1 future_1-start ...
         * pool-1-thread-2 future_2-start ...
         * main end ...
         * pool-1-thread-1 future_1-end ...
         * pool-1-thread-2 future_2-end ...
         * f3 = 143
         */
    }

5 组合任务

public class CompletableFuture组合任务Test {
    static ThreadPoolExecutor executor = new ThreadPoolExecutor(5,
            50,
            10,
            TimeUnit.SECONDS,
            new LinkedBlockingQueue<>(100),
            Executors.defaultThreadFactory(),
            new ThreadPoolExecutor.AbortPolicy());

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        System.out.println("main start ...");
        CompletableFuture<Integer> future_1 = CompletableFuture.supplyAsync(() -> {
            System.out.println(Thread.currentThread().getName() + " future_1-start ...");
            try {
                TimeUnit.SECONDS.sleep(3);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println(Thread.currentThread().getName() + " future_1-end ...");
            return 11;
        }, executor);

        CompletableFuture<Integer> future_2 = CompletableFuture.supplyAsync(() -> {
            System.out.println(Thread.currentThread().getName() + " future_2-start ...");
            try {
                TimeUnit.SECONDS.sleep(5);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println(Thread.currentThread().getName() + " future_2-end ...");
            return 22;
        }, executor);

        CompletableFuture<Integer> future_3 = CompletableFuture.supplyAsync(() -> {
            System.out.println(Thread.currentThread().getName() + " future_3-start ...");
            try {
                TimeUnit.SECONDS.sleep(8);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println(Thread.currentThread().getName() + " future_3-end ...");
            return 33;
        }, executor);

//        allOf(future_1, future_2, future_3);
//        allOf_2(future_1, future_2, future_3);
        anyOf(future_1, future_2, future_3);

    }
}

1 allOf

当所有给定的 CompletableFuture 完成时,返回一个新的 CompletableFuture

    private static void allOf(CompletableFuture<Integer> future_1, CompletableFuture<Integer> future_2, CompletableFuture<Integer> future_3) {
        /**
         * public static CompletableFuture<Void> allOf(CompletableFuture<?>... cfs){}
         */
        CompletableFuture<Void> future = CompletableFuture.allOf(future_1, future_2, future_3);
        System.out.println("main end ...");

        /**
         * main start ...
         * pool-1-thread-1 future_1-start ...
         * pool-1-thread-2 future_2-start ...
         * pool-1-thread-3 future_3-start ...
         * main end ...
         * pool-1-thread-1 future_1-end ...
         * pool-1-thread-2 future_2-end ...
         * pool-1-thread-3 future_3-end ...
         */
    }
    private static void allOf_2(CompletableFuture<Integer> future_1, CompletableFuture<Integer> future_2, CompletableFuture<Integer> future_3) throws ExecutionException, InterruptedException {
        /**
         * public static CompletableFuture<Void> allOf(CompletableFuture<?>... cfs){}
         */
        CompletableFuture<Void> future = CompletableFuture.allOf(future_1, future_2, future_3);
        future.get();
        System.out.println("main end ...");
        /**
         *main start ...
         * pool-1-thread-1 future_1-start ...
         * pool-1-thread-2 future_2-start ...
         * pool-1-thread-3 future_3-start ...
         * pool-1-thread-1 future_1-end ...
         * pool-1-thread-2 future_2-end ...
         * pool-1-thread-3 future_3-end ...
         * main end ...
         */

    }

2 anyOf

当任何一个给定的CompletablFuture完成时,返回一个新的CompletableFuture

    private static void anyOf(CompletableFuture<Integer> future_1, CompletableFuture<Integer> future_2, CompletableFuture<Integer> future_3) throws ExecutionException, InterruptedException {
        /**
         * public static CompletableFuture<Object> anyOf(CompletableFuture<?>... cfs)
         */
        CompletableFuture<Object> future = CompletableFuture.anyOf(future_1, future_2, future_3);
        future.get();
        System.out.println("main end ...");
        /**
         * main start ...
         * pool-1-thread-1 future_1-start ...
         * pool-1-thread-2 future_2-start ...
         * pool-1-thread-3 future_3-start ...
         * pool-1-thread-1 future_1-end ...
         * main end ...
         * pool-1-thread-2 future_2-end ...
         * pool-1-thread-3 future_3-end ...
         */
    }
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值