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

相關文章
相關標籤/搜索