CompletableFuture是用來描述多線程任務的時序關係的:串行關係,並行關係,聚合關係。java
CompletableFuture 是Java 8 新增長的Api,該類實現,Future和CompletionStage兩個接口,提供了很是強大的Future的擴展功能,能夠幫助咱們簡化異步編程的複雜性,提供了函數式編程的能力,能夠經過回調的方式處理計算結果,而且提供了轉換和組合CompletableFuture的方法。編程
方式一:使用默認線程池多線程
/** * 建立一個不帶返回值得任務。 */ CompletableFuture<Void> f1 = CompletableFuture.runAsync(new Runnable() { @Override public void run() { //業務邏輯 } }); /** * 建立一個帶返回值的任務。 */ CompletableFuture<String> f2 = CompletableFuture.supplyAsync(new Supplier<String>() { @Override public String get() { //業務邏輯 return null; } });
方式二:使用自定義線程池(建議使用)app
//建立線程池 ExecutorService executor = Executors.newFixedThreadPool(10); //建立一個不帶返回值得任務。 CompletableFuture<Void> f1 = CompletableFuture.runAsync(new Runnable() { @Override public void run() { } },executor); //建立一個帶返回值的任務。 CompletableFuture<String> f2 = CompletableFuture.supplyAsync(new Supplier<String>() { @Override public String get() { //業務邏輯 return null; } },executor);
CompletionStage接口能夠清晰地描述任務之間的這種時序關係,時序關係:串行,並行,匯聚。dom
線程與線程之間的執行順序是串行的。異步
//Async表明的是異步執行fn CompletionStage<R> thenApply(fn); CompletionStage<R> thenApplyAsync(fn); CompletionStage<Void> thenAccept(consumer); CompletionStage<Void> thenAcceptAsync(consumer); CompletionStage<Void> thenRun(action); CompletionStage<Void> thenRunAsync(action); CompletionStage<R> thenCompose(fn); CompletionStage<R> thenComposeAsync(fn);
CompletionStage接口裏面描述串行關係,主要是thenApply、thenAccept、thenRun和thenCompose這四 個系列的接口。ide
thenApply系列函數裏參數fn的類型是接口Function<T,R>,這個接口裏與CompletionStage相關的方法是R apply(T t),這個方法既能接收參數也支持返回值,因此thenApply系列方法返回的是CompletionStage<R>。函數式編程
而thenAccept系列方法裏參數consumer的類型是接口Consumer<T>,這個接口裏與CompletionStage相關 的方法是voidaccept(T t),這個方法雖然支持參數,但卻不支持回值,因此thenAccept系列方法返回的是CompletionStage<Void>。異步編程
thenRun系列方法裏action的參數是Runnable,因此action既不能接收參數也不支持返回值,因此thenRun 系列方法返回的也是CompletionStage<Void>。函數
這些方法裏面Async表明的是異步執行fn、consumer或者action。其中,須要你注意的是thenCompose系列方法,這個系列的方法會新建立出一個子流程,最終結果和thenApply系列是相同的。
演示串行
//supplyAsync()啓動一個異步 流程 CompletableFuture<String> f0 = CompletableFuture.supplyAsync( () -> "Hello World") //① .thenApply(s -> s + "girl") //② .thenApply(String::toUpperCase);//③ System.out.println(f0.join()); //輸出結果 HELLO WORLD girl
雖然這是一個異步流程,但任務①②③倒是 串行執行的,②依賴①的執行結果,③依賴②的執行結果。
CompletionStage接口裏面描述AND匯聚關係,主要是thenCombine、thenAcceptBoth和runAfterBoth系列的接口,這些接口的區別也是源自fn、consumer、action這三個核心參數不一樣。
CompletionStage<R> thenCombine(other,fn); CompletionStage<R> thenCombineAsync(other,fn); CompletionStage<Void> thenAcceptBoth(other,consumer); CompletionStage<Void> thenAcceptBothAsync(other,consumer); CompletionStage<Void> runAfterBoth(other, action); CompletionStage<Void> runAfterBothAsync(other, action);
演示:
// 啓動一個異步流程f1 CompletableFuture<Void> f1 = CompletableFuture.runAsync(()->{ System.out.println("異步任務-1"); }); // 啓動一個異步流程f2 CompletableFuture<String> f2 = CompletableFuture.supplyAsync(()->{ String s = "異步任務-2"; System.out.println(s); return s; }); //啓動一個匯聚流程f3 CompletableFuture<String> f3 = f1.thenCombine(f2,(a,tf)->{ return tf;//tf是f2的值 }); //等待任務3執行結果 System.out.println(f3.join());
CompletionStage接口裏面描述OR匯聚關係,主要是applyToEither、acceptEither和runAfterEither系列的 接口,這些接口的區別也是源自fn、consumer、action這三個核心參數不一樣。
CompletionStage applyToEither(other, fn); CompletionStage applyToEitherAsync(other, fn); CompletionStage acceptEither(other, consumer); CompletionStage acceptEitherAsync(other, consumer); CompletionStage runAfterEither(other, action); CompletionStage runAfterEitherAsync(other, action);
功能演示:
// 啓動一個異步流程f1 CompletableFuture<String> f1 = CompletableFuture.supplyAsync(()->{ int t = new Random().nextInt(10); System.out.println("f1-t = "+t); sleep(t, TimeUnit.SECONDS); return String.valueOf(t); }); // 啓動一個異步流程f2 CompletableFuture<String> f2 = CompletableFuture.supplyAsync(()->{ int t = new Random().nextInt(10); System.out.println("f2-t = "+t); sleep(t, TimeUnit.SECONDS); return String.valueOf(t); }); //將f1和f2的值彙總到f3 CompletableFuture<String> f3 = f1.applyToEither(f2,s -> Integer.parseInt(f2.join())+Integer.parseInt(s)+"" ); System.out.println(f3.join());
**** 碼字不易若是對你有幫助請給個關注****
**** 愛技術愛生活 QQ羣: 894109590****