Java并发包 Future 续二

CompletionStage接口

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

CompletableFuture

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

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

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

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

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

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

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

方法
CompletableFuture runAsync(Runnable runnable)
CompletableFuture runAsync(Runnable runnable,Executor executor)
supplyAsync(Supplier supplier)
CompletableFuture supplyAsync(Supplier 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 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 whenComplete(BiConsumer action)
public CompletableFuture whenCompleteAsync(BiConsumer action)
public CompletableFuture whenCompleteAsync(BiConsumer action, Executor executor)
public CompletableFuture exceptionally(Function 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 CompletableFuture thenApply(Function fn)
public CompletableFuture thenApplyAsync(Function fn)
public CompletableFuture thenApplyAsync(Function fn, Executor executor)

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

方法
public CompletionStage handle(BiFunction fn);
public CompletionStage handleAsync(BiFunction fn);
public CompletionStage handleAsync(BiFunction fn,Executor executor);

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

方法
public CompletionStage thenAccept(Consumer action);
public CompletionStage thenAcceptAsync(Consumer action);
public CompletionStage thenAcceptAsync(Consumer action,Executor executor);

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

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

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

方法
public CompletionStage thenCombine(CompletionStage other,BiFunction fn);
public CompletionStage thenCombineAsync(CompletionStage other,BiFunction fn);
public CompletionStage thenCombineAsync(CompletionStage other,BiFunction fn,Executor executor);

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

方法
public CompletionStage thenAcceptBoth(CompletionStage other,BiConsumer action)
public CompletionStage thenAcceptBothAsync(CompletionStage other,BiConsumer action)
public CompletionStage thenAcceptBothAsync(CompletionStage other,BiConsumer action, Executor executor)

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

方法
public CompletionStage applyToEither(CompletionStage other,Function fn)
public CompletionStage applyToEitherAsync(CompletionStage other,Function fn)
public CompletionStage applyToEitherAsync(CompletionStage other,Function fn,Executor executor)

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

方法
public CompletionStage acceptEither(CompletionStage other,Consumer action);
public CompletionStage acceptEitherAsync(CompletionStage other,Consumer action);
public CompletionStage acceptEitherAsync(CompletionStage other,Consumer action,Executor executor);

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

方法
public CompletionStage runAfterEither(CompletionStage other,Runnable action);
public CompletionStage runAfterEitherAsync(CompletionStage other,Runnable action);
public CompletionStage runAfterEitherAsync(CompletionStage other,Runnable action,Executor executor);

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

方法
public CompletionStage runAfterBoth(CompletionStage other,Runnable action);
public CompletionStage runAfterBothAsync(CompletionStage other,Runnable action);
public CompletionStage runAfterBothAsync(CompletionStage other,Runnable action,Executor executor);

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

方法
public CompletableFuture thenCompose(Function> fn);
public CompletableFuture thenComposeAsync(Function> fn) ;
public CompletableFuture thenComposeAsync(Function> fn, Executor executor) ;

  • https://blog.csdn.net/u011726984/article/details/79320004
  • https://www.jianshu.com/p/6bac52527ca4

你可能感兴趣的:(Java并发包 Future 续二)