就不介紹了,直接貼代碼,建議在代碼中使用,真的很方便
package cn.hou.completablefuture; import org.junit.Test; import java.util.concurrent.*; public class CompletableFutureDemo { /** * 在Java8中,CompletableFuture提供了非常強大的Future的擴展功能,可以幫助我們簡化異步編程的復雜性, * 並且提供了函數式編程的能力,可以通過回調的方式處理計算結果,也提供了轉換和組合 CompletableFuture 的方法 * * 注意: 方法中有Async一般表示另起一個線程,沒有表示用當前線程 */ @Test public void test01() throws Exception { ExecutorService service = Executors.newFixedThreadPool(5); /** * supplyAsync用於有返回值的任務, * runAsync則用於沒有返回值的任務 * Executor參數可以手動指定線程池,否則默認ForkJoinPool.commonPool()系統級公共線程池 */ CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> { try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); } return "侯征"; }, service); CompletableFuture<Void> data = CompletableFuture.runAsync(() -> System.out.println("侯征")); /** * 計算結果完成回調 */ future.whenComplete((x,y)-> System.out.println(x+","+y)); //執行當前任務的線程執行繼續執 data.whenCompleteAsync((x,y)-> System.out.println(x+","+y)); // 交給線程池另起線程執行 future.exceptionally(Throwable::toString); //System.out.println(future.get()); /** * thenApply,一個線程依賴另一個線程可以使用,出現異常不執行 */ //第二個線程依賴第一個的結果 CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> 5).thenApply(x -> x); /** * handle 是執行任務完成時對結果的處理,第一個出現異常繼續執行 */ CompletableFuture<Integer> future2 = future1.handleAsync((x, y) -> x + 2); System.out.println(future2.get());//7 /** * thenAccept 消費處理結果,不返回 */ future2.thenAccept(System.out::println); /** * thenRun 不關心任務的處理結果。只要上面的任務執行完成,就開始執行 */ future2.thenRunAsync(()-> System.out.println("繼續下一個任務")); /** * thenCombine 會把 兩個 CompletionStage 的任務都執行完成后,兩個任務的結果交給 thenCombine 來處理 */ CompletableFuture<Integer> future3 = future1.thenCombine(future2, Integer::sum); System.out.println(future3.get()); // 5+7=12 /** * thenAcceptBoth : 當兩個CompletionStage都執行完成后,把結果一塊交給thenAcceptBoth來進行消耗 */ future1.thenAcceptBothAsync(future2,(x,y)-> System.out.println(x+","+y)); //5,7 /** * applyToEither * 兩個CompletionStage,誰執行返回的結果快,我就用那個CompletionStage的結果進行下一步的轉化操作 */ CompletableFuture<Integer> future4 = future1.applyToEither(future2, x -> x); System.out.println(future4.get()); //5 /** * acceptEither * 兩個CompletionStage,誰執行返回的結果快,我就用那個CompletionStage的結果進行下一步的消耗操作 */ future1.acceptEither(future2, System.out::println); /** * runAfterEither * 兩個CompletionStage,任何一個完成了都會執行下一步的操作(Runnable */ future1.runAfterEither(future,()-> System.out.println("有一個完成了,我繼續")); /** * runAfterBoth * 兩個CompletionStage,都完成了計算才會執行下一步的操作(Runnable) */ future1.runAfterBoth(future,()-> System.out.println("都完成了,我繼續")); /** * thenCompose 方法 * thenCompose 方法允許你對多個 CompletionStage 進行流水線操作,第一個操作完成時,將其結果作為參數傳遞給第二個操作 * thenApply是接受一個函數,thenCompose是接受一個future實例,更適合處理流操作 */ future1.thenComposeAsync(x->CompletableFuture.supplyAsync(()->x+1)) .thenComposeAsync(x->CompletableFuture.supplyAsync(()->x+2)) .thenCompose(x->CompletableFuture.runAsync(()-> System.out.println("流操作結果:"+x))); TimeUnit.SECONDS.sleep(5);//主線程sleep,等待其他線程執行 } }