美文网首页技术栈
2019-04-02——Java并发包 Future 续二

2019-04-02——Java并发包 Future 续二

作者: 烟雨乱平生 | 来源:发表于2019-04-02 15:09 被阅读0次

    CompletionStage接口

    CompletionStage代表异步计算过程中的某一个阶段,一个阶段完成以后可能会触发另外一个阶段。一个阶段的计算执行可以是一个Function,Consumer或者Runnable。一个阶段的执行可能是被单个阶段的完成触发,也可能是由多个阶段一起触发

    CompletableFuture实现了Future接口的如下策略:

    • CompletableFuture无法直接控制完成,所以cancel操作被视为是另一种异常完成形式。方法isCompletedExceptionally可以用来确定一个CompletableFuture是否以任何异常的方式完成。
    • 以一个CompletionException为例,方法get()和get(long,TimeUnit)抛出一个ExecutionException,对应CompletionException。为了在大多数上下文中简化用法,这个类还定义了方法join()和getNow,而不是直接在这些情况中直接抛出CompletionException。

    CompletableFuture

    JDK5新增了Future接口,用于描述一个异步计算的结果。虽然 Future 以及相关使用方法提供了异步执行任务的能力,但是对于结果的获取却是很不方便,只能通过阻塞或者轮询的方式得到任务的结果。阻塞的方式显然和我们的异步编程的初衷相违背,轮询的方式又会耗费无谓的 CPU 资源,而且也不能及时地得到计算结果。

    在Java8中,CompletableFuture提供了非常强大的Future的扩展功能,可以帮助我们简化异步编程的复杂性,并且提供了函数式编程的能力,可以通过回调的方式处理计算结果,也提供了转换和组合 CompletableFuture 的方法。

    它实现了Future和CompletionStage接口

    CompletableFuture实现了CompletionStage接口的如下策略:

    • 为了完成当前的CompletableFuture接口或者其他完成方法的回调函数的线程,提供了非异步的完成操作。
    • 没有显式入参Executor的所有async方法都使用ForkJoinPool.commonPool()为了简化监视、调试和跟踪,所有生成的异步任务都是标记接口AsynchronousCompletionTask的实例。
    • 所有的CompletionStage方法都是独立于其他共有方法实现的,因此一个方法的行为不会受到子类中其他方法的覆盖。

    CompletableFuture 提供了四个静态方法来创建一个异步操作。

    方法
    CompletableFuture<Void> runAsync(Runnable runnable)
    CompletableFuture<Void> runAsync(Runnable runnable,Executor executor)
    supplyAsync(Supplier<U> supplier)
    <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier,Executor executor)
    static void runAsync() throws ExecutionException, InterruptedException {
        CompletableFuture future = CompletableFuture.runAsync(()->{
            String value = "this is runAsync";
            System.out.println(value);
        });
        Object o = future.get();
        System.out.println(o);
    }
    
    static void supplyAsync() throws ExecutionException, InterruptedException {
        CompletableFuture<String> future = CompletableFuture.supplyAsync(()->{
            String value = "this is supplyAsync";
            System.out.println(value);
            return value;
        });
        String o = future.get();
        System.out.println(o);
    }
    

    其中supplyAsync用于有返回值的任务,runAsync则用于没有返回值的任务。Executor参数可以手动指定线程池,否则默认ForkJoinPool.commonPool()系统级公共线程池

    计算结果完成时的回调方法
    当CompletableFuture的计算结果完成,或者抛出异常的时候,可以执行特定的Action。

    方法
    public CompletableFuture<T> whenComplete(BiConsumer<? super T,? super Throwable> action)
    public CompletableFuture<T> whenCompleteAsync(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)
    static void whenComplete(){
        CompletableFuture.supplyAsync(()->{
            String value = "this is supplyAsync";
            System.out.println(value);
            return value;
        }).whenComplete((s, throwable) -> {
            System.out.println("this is accept");
            System.out.println(s);
            System.out.println(throwable);
        });
    }
    
    
    static void exceptionally() throws ExecutionException, InterruptedException {
        CompletableFuture future = CompletableFuture.supplyAsync(()->{
            String value = "this is supplyAsync";
            System.out.println(Integer.valueOf(value));
            return value;
        }).exceptionally(throwable -> {
            System.out.println(throwable);
            return "执行报错";
        });
        Object o = future.get();
        System.out.println(o);
    }
    

    whenComplete 和 whenCompleteAsync 的区别:

    • whenComplete:是执行当前任务的线程执行继续执行 whenComplete 的任务。

    • whenCompleteAsync:是执行把 whenCompleteAsync 这个任务继续提交给线程池来进行执行。

    thenApply 方法
    当一个线程依赖另一个线程时,可以使用 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)

    handle 方法
    handle 是执行任务完成时对结果的处理。handle 方法和 thenApply 方法处理方式基本一样。不同的是 handle 是在任务完成后再执行,还可以处理异常的任务。thenApply 只可以执行正常的任务,任务出现异常则不执行 thenApply 方法。

    方法
    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);

    thenAccept 消费处理结果
    接收任务的处理结果,并消费处理,无返回结果。

    方法
    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);

    thenRun 方法
    跟 thenAccept 方法不一样的是,不关心任务的处理结果。只要上面的任务执行完成,就开始执行 thenAccept 。

    方法
    public CompletionStage<Void> thenRun(Runnable action)
    public CompletionStage<Void> thenRunAsync(Runnable action)
    public CompletionStage<Void> thenRunAsync(Runnable action,Executor executor)

    thenCombine 合并任务
    thenCombine 会把 两个 CompletionStage 的任务都执行完成后,把两个任务的结果一块交给 thenCombine 来处理。

    方法
    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);

    thenAcceptBoth
    当两个CompletionStage都执行完成后,把结果一块交给thenAcceptBoth来进行消耗

    方法
    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)

    applyToEither 方法
    两个CompletionStage,谁执行返回的结果快,我就用那个CompletionStage的结果进行下一步的转化操作。

    方法
    public <U> CompletionStage<U> applyToEither(CompletionStage<? extends T> other,Function<? super T, U> fn)
    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)

    acceptEither 方法
    两个CompletionStage,谁执行返回的结果快,我就用那个CompletionStage的结果进行下一步的消耗操作。

    方法
    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);

    runAfterEither 方法
    两个CompletionStage,任何一个完成了都会执行下一步的操作(Runnable)

    方法
    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);

    runAfterBoth
    两个CompletionStage,都完成了计算才会执行下一步的操作(Runnable)

    方法
    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);

    thenCompose
    thenCompose 方法允许你对两个 CompletionStage 进行流水线操作,第一个操作完成时,将其结果作为参数传递给第二个操作。

    方法
    public <U> CompletableFuture<U> thenCompose(Function<? super T, ? extends CompletionStage<U>> fn);
    public <U> CompletableFuture<U> thenComposeAsync(Function<? super T, ? extends CompletionStage<U>> fn) ;
    public <U> CompletableFuture<U> thenComposeAsync(Function<? super T, ? extends CompletionStage<U>> fn, Executor executor) ;

    相关文章

      网友评论

        本文标题:2019-04-02——Java并发包 Future 续二

        本文链接:https://www.haomeiwen.com/subject/cizwbqtx.html