CompletableFuture

感受很久没有更新点东西了,本身都看不下去了啊……java

前言

CompletableFuture 是 java8 提供的功能,java8至今已经挺久了,因此也不能算新东西,不过以前android的开发不太用到java8的特性,就连stream也用的是rxjava。android

Future

在理解CompletableFuture,先理解Future仍是很是重要的。由于CompletableFuture算是Future的加强版。 Future用于表示一个带返回值的异步计算过程。内部方法包括获取返回值,cancel任务,查看任务是否完成等。 Future有几个继承编程

  • RunnableFuture 同时继承了Runnable和 Future的一个接口。最经常使用的FutureTask就是这个接口的实现类。ExecutorThreadPool调用submit方法就会建立一个FutureTask对象的返回。
  • ScheduledFuture 继承了Future 和 Delayed 接口的一个接口,用于表示一个带delay效果的Future。而后RunnableScheduledFuture 进一步继承了ScheduledFuture 和 RunnableFuture,实际上就表示一个带有delay和周期运行功能的 RunnableFuture。他的最终实现类就是ScheduledFutureTask. 经过 ScheduledThreadPoolExecutor 线程池,调用schedule方法,实际返回的就是一个 ScheduledFutureTask。

Future还有几种继承类型,这个就和每个知识点绑定来讲,好比CompletableFuture,实际上也是Future的继承者。dom

CompletableFuture

实际上,CompletableFuture 的核心思想是函数式编程,这在java8中的流式机制stream中也有体现。在之前android开发中,承担起函数式开发重任的基础库是rxjava,不过在服务端开发中这个库并非很经常使用,直接使用java8的特性就能实现大部分流操做。异步

CompletionStage

CompletionStage 类是CompletableFuture任务链的中间类,表示一个阶段状态,CompletableFuture自己就继承了这个接口,实际使用中咱们不多直接用到这个类。不过CompletableFuture的流式功能就是经过这个类定义的,好比thenAccept等这些方法。ide

runAsync 和 supplyAsync方法

CompletableFuture 提供了四个静态方法来建立一个异步操做。函数式编程

public static CompletableFuture<Void> runAsync(Runnable runnable)
public static CompletableFuture<Void> runAsync(Runnable runnable, Executor executor)
public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)
public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier, Executor executor)

没有指定Executor的方法会使用ForkJoinPool.commonPool() 做为它的线程池执行异步代码。若是指定线程池,则使用指定的线程池运行。如下全部的方法都类同。函数

  • runAsync方法不支持返回值。
  • supplyAsync能够支持返回值。
//无返回值
public static void runAsync() throws Exception {
    CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
        }
        System.out.println("run end ...");
    });

    future.get();
}

//有返回值
public static void supplyAsync() throws Exception {
    CompletableFuture<Long> future = CompletableFuture.supplyAsync(() -> {
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
        }
        System.out.println("run end ...");
        return System.currentTimeMillis();
    });

    long time = future.get();
    System.out.println("time = "+time);
}

流式方法

在开启一个CompleteFuture以后,后续就可使用流式方法了,好比thenAccept表示消费处理结果。线程

public static void thenAccept() throws Exception{
    CompletableFuture<Void> future = CompletableFuture.supplyAsync(new Supplier<Integer>() {
        @Override
        public Integer get() {
            return new Random().nextInt(10);
        }
    }).thenAccept(integer -> {
        System.out.println(integer);
    });
    future.get();
}

thenAccept消费了前一步返回的结果。顺带一提,还有一个thenAcceptAsync.code

  • thenAccept:是执行当前任务的线程执行继续执行 thenAccept 的任务。
  • thenAcceptAsync:是执行把 thenAcceptAsync 这个任务继续提交给线程池来进行执行。

流式还有很多方法,不过不必穷举说明,须要用到的时候查一下就行了。

参考

https://www.jianshu.com/p/6bac52527ca4

相关文章
相关标签/搜索