异步调用(多线程)
異步調用
- Future
- CompletableFuture
- 異步開啟
- 案例:
- 方法說明
- runAsync
- supplyAsync
- thenRun
- thenApply
- thenAccept
- thenCompose
- thenCombine(and聚合)
- thenAcceptBoth(and聚合)
- runAfterBoth(and聚合)
- applyToEither(or聚合)
- exceptionally(異常處理)
- whenComplete(異常處理)
- handle(異常處理)
- 所有代碼
- 網(wǎng)上找的參考Demo
Future
一般不使用Future
Future 也是一個異步計算結果返回接口,目的獲取返回值結果。但是 future 在獲取返回值結構的時候,方法必須同步阻塞等待返回值結果。Get : 獲取結果(等待,阻塞)Get(timeout) : 獲取結果,指定等待時間Cancel : 取消當前任務isDone : 判斷任務是否已經(jīng)完成 (輪詢) futrure 對于結果獲取不是很方便,只能通過同步阻塞的方式獲取結果,或者是輪詢的方式獲取到結果;阻塞的方式獲取返回值結果與異步的思想想違背,輪詢方式又很占用 cpu 資源,也不能及時得到我們結果。CompletableFuture
即異步編排
CompletableFuture可以幫助我們簡化異步編程復雜性,提供了函數(shù)式編程的能力,可以通過回調函數(shù)的方式處理計算結果。public class CompletableFuture<T> implements Future<T>, CompletionStage<T>CompletableFuture 具有Future 的特性,還實現(xiàn)了CompletionStage 接口,具備CompletionStage接口的特性: 串行執(zhí)行,并行執(zhí)行,聚合(AND 聚合,OR 聚合)1.串行關系執(zhí)行then – 然后,也就是表示下一步,所以通常是一個串行的關系體現(xiàn),then后面的單詞(比如 run/apply/accept)就是函數(shù)是接口中抽象方法名稱;利用上一步的執(zhí)行結果,去進行下一步任務執(zhí)行,任務執(zhí)行具有先后順序,因此把這種操作叫做串行關系public CompletionStage<Void> thenRun(Runnable action);public CompletionStage<Void> thenRunAsync(Runnable action);public CompletableFuture<Void> thenRunAsync(Runnable action,Executor executor);public <U> CompletableFuture<U> thenApply( Function<? super T,? extends U> fn) ;public <U> CompletionStage<U> thenApplyAsync(Function<? super T,? extends U> fn);public <U> CompletionStage<U> thenApplyAsync(Function<? super T,? extends U> fn,Executor executor);public CompletionStage<Void> thenAccept(Consumer<? super T> action);public CompletionStage<Void> thenAcceptAsync(Consumer<? super T> action);public CompletionStage<Void> thenAcceptAsync(Consumer<? super T> action, Executor executor);public <U> CompletionStage<U> thenCompose(Function<? super T, ? extends CompletionStage<U>> fn);public <U> CompletionStage<U> thenComposeAsync(Function<? super T, ? extends CompletionStage<U>> fn);public <U> CompletionStage<U> thenComposeAsync(Function<? super T, ? extends CompletionStage<U>> fn, Executor executor);2.聚合andCombine…… with …… 和 both…… and …… 都是要求兩者都必須滿足,也就是and 且的關系。public <U,V> CompletionStage<V> thenCombine (CompletionStage<? extends U> other, BiFunction<? super T,? super U,? extends V> fn);public <U,V> CompletionStage<V> thenCombineAsync (CompletionStage<? extends U> other, BiFunction<? super T,? super U,? extends V> fn);public <U,V> CompletionStage<V> thenCombineAsync (CompletionStage<? extends U> other, BiFunction<? super T,? super U,? extends V> fn, Executor executor);public <U> CompletionStage<Void> thenAcceptBoth (CompletionStage<? extends U> other, BiConsumer<? super T, ? super U> action);public <U> CompletionStage<Void> thenAcceptBothAsync (CompletionStage<? extends U> other, BiConsumer<? super T, ? super U> action);public <U> CompletionStage<Void> thenAcceptBothAsync(CompletionStage<? extends U> other, BiConsumer<? super T, ? super U> action, Executor executor);public CompletionStage<Void> runAfterBoth(CompletionStage<?> other, Runnable action);public CompletionStage<Void> runAfterBothAsync(CompletionStage<?> other, Runnable action);public CompletionStage<Void> runAfterBothAsync(CompletionStage<?> other, Runnable action, Executor executor);3.聚合orpublic <U> CompletionStage<U> applyToEitherAsync (CompletionStage<? extends T> other, Function<? super T, U> fn);public <U> CompletionStage<U> applyToEitherAsync (CompletionStage<? extends T> other, Function<? super T, U> fn, Executor executor);public <U> CompletionStage<U> applyToEitherAsync (CompletionStage<? extends T> other, Function<? super T, U> fn);public <U> CompletionStage<U> applyToEitherAsync (CompletionStage<? extends T> other, Function<? super T, U> fn, Executor executor);public CompletionStage<Void> acceptEither (CompletionStage<? extends T> other, Consumer<? super T> action);public CompletionStage<Void> acceptEitherAsync (CompletionStage<? extends T> other, Consumer<? super T> action);public CompletionStage<Void> acceptEitherAsync (CompletionStage<? extends T> other, Consumer<? super T> action, Executor executor);public CompletionStage<Void> runAfterEither(CompletionStage<?> other, Runnable action);public CompletionStage<Void> runAfterEitherAsync (CompletionStage<?> other, Runnable action);public CompletionStage<Void> runAfterEitherAsync (CompletionStage<?> other, Runnable action, Executor executor);4.異常處理public CompletionStage<T> exceptionally(Function<Throwable, ? extends T> fn);public CompletionStage<T> whenComplete (BiConsumer<? super T, ? super Throwable> action);public CompletionStage<T> whenCompleteAsync (BiConsumer<? super T, ? super Throwable> action);public CompletionStage<T> whenCompleteAsync (BiConsumer<? super T, ? super Throwable> action, Executor executor);public <U> CompletionStage<U> handle (BiFunction<? super T, Throwable, ? extends U> fn);public <U> CompletionStage<U> handleAsync (BiFunction<? super T, Throwable, ? extends U> fn);public <U> CompletionStage<U> handleAsync (BiFunction<? super T, Throwable, ? extends U> fn, Executor executor);異步開啟
異步開啟CompletableFuture 提供了 4 個靜態(tài)的方法,來創(chuàng)建一個異步操作(異步開啟: 從這 4 個靜態(tài)的方法開發(fā)即可) 1.runAsync方法:沒有返回值的方法,不關注返回值public static CompletableFuture<Void> runAsync(Runnable runnable);public static CompletableFuture<Void> runAsync(Runnable runnable,Executor executor); 2.supplyAsync :有返回值,關注返回值的。public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier);public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier,Executor executor)案例:
方法說明
1.runAsync 沒有返回值 2.1 public static CompletableFuture<Void> runAsync(Runnable runnable); 使用默認的線程池 2.2 public static CompletableFuture<Void> runAsync(Runnable runnable, Executor executor) 自定義線程池 <p> 2.supplyAsync: 有返回值的,關注返回值 2.1 public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier) 使用默認的線程池 2.3 public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier, Executor executor) 自定義線程池 <p> 3. thenRun 第一步執(zhí)行完執(zhí)行第二步,第二步的不關心第一執(zhí)行的結果 3.1 public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier) 3.2 public CompletableFuture<Void> thenRun(Runnable action) 不關心返回值,也不關心也行結果,只有順序,1執(zhí)行后2才會執(zhí)行 <p> 4. thenApply 有返回值U,也關心上一步的返回值,上一步的返回值會被當成參數(shù),參數(shù)類型為T,也是順序執(zhí)行,1執(zhí)行后執(zhí)行2 4.1 public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier) 4.2 public <U> CompletableFuture<U> thenApply(Function<? super T,? extends U> fn); <p> 5. thenAccept 沒有返回結果,關心上一步的執(zhí)行結果,上一步的執(zhí)行結果會被當成參數(shù),參數(shù) T 5.1 public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier) 5.2 public CompletableFuture<Void> thenAccept(Consumer<? super T> action) <p> 6. thenCompose 有返回值,順序執(zhí)行,第一步的返回結果為thenCompose的參數(shù),允許對2個CompletionStage流水線進行操作,第一個操作完成時,將第一個的結果作為第二個參數(shù) public <U> CompletableFuture<U> thenCompose(Function<? super T, ? extends CompletionStage<U>> fn) <p> 7.thenCombine 7.1 聚合and,有返回值 當 7.2 把兩個任務都執(zhí)行完畢后,會將兩個結果都交給thenCombine去處理 7.3 thenAcceptBoth(沒有返回值)與 thenCombine(有返回值)的區(qū)別 public <U,V> CompletableFuture<V> thenCombine( CompletionStage<? extends U> other, BiFunction<? super T,? super U,? extends V> fn) <p> 8.thenAcceptBoth 8.1 聚合and 8.2 沒有返回值 會把兩個任務都執(zhí)行完畢后,回將兩個結果都交給thenAcceptBoth去處理 public <U> CompletableFuture<Void> thenAcceptBoth( CompletionStage<? extends U> other, BiConsumer<? super T, ? super U> action) <p> 9.runAfterBoth 9.1 聚合and 9.2沒有返回值, 9.3當有連個任務時,兩個任務都執(zhí)行完,在執(zhí)行下一個任務 public CompletableFuture<Void> runAfterBoth(CompletionStage<?> other,Runnable action); <p> 10. applyToEither 10.1 聚合 or 10.2 有返回值 10.2 針對2個CompletionStage,將計算速度最快的那個CompletionStage的結果作為下一步的處理 public <U> CompletableFuture<U> applyToEither(CompletionStage<? extends T> other, Function<? super T, U> fn); <p> 11.exceptionally 11.1 異常處理 11.2 有返回值 簡單理解 就是當程序執(zhí)行錯誤進入exceptionally方法 public CompletableFuture<T> exceptionally( Function<Throwable, ? extends T> fn) <p> 12.whenComplete 可以獲取到上一次的返回結果 public CompletableFuture<T> whenComplete(BiConsumer<? super T, ? super Throwable> action) <p> 13. handle 有返回值 相當于 try()finally() ,可以對執(zhí)行結果進行處理,也可以對異常信息進行處理public <U> CompletableFuture<U> handle( BiFunction<? super T, Throwable, ? extends U> fn)runAsync
1.public static CompletableFuture runAsync(Runnable runnable);
public static void main(String[] args) throws ExecutionException, InterruptedException {log.info("主線程start……");/*** 異步任務* 沒有返回值,為定義線程池* public static CompletableFuture<Void> runAsync(Runnable runnable);*/CompletableFuture<Void> runAsync = CompletableFuture.runAsync(() -> {log.info("子線程future線程start……");int i = 10 / 2;log.info("線程名稱:{},線程執(zhí)行結果:{}", Thread.currentThread().getName(), i);log.info("子線程future線程end……");});// 調用異步任務runAsync.get();log.info("主線程end……"); }2.public static CompletableFuture runAsync(Runnable runnable, Executor executor)
public static void main(String[] args) throws ExecutionException, InterruptedException {AsyFutureDemo.runAsync();}/*** 線程池對象*/public static ThreadPoolExecutor threadPool = new ThreadPoolExecutor(Runtime.getRuntime().availableProcessors(),Runtime.getRuntime().availableProcessors() + 1,3,TimeUnit.SECONDS,new LinkedBlockingQueue<Runnable>(3),Executors.defaultThreadFactory(),new ThreadPoolExecutor.CallerRunsPolicy());public static void runAsync() throws ExecutionException, InterruptedException {log.info("主線程start……");/*** 異步任務* 沒有返回值,為定義線程池* public static CompletableFuture<Void> runAsync(Runnable runnable);*/CompletableFuture<Void> runAsync = CompletableFuture.runAsync(() -> {log.info("子線程future線程start……");int i = 10 / 2;log.info("線程名稱:{},線程執(zhí)行結果:{}", Thread.currentThread().getName(), i);log.info("子線程future線程end……");}, threadPool);// 調用異步任務runAsync.get();log.info("主線程end……");}supplyAsync
public static CompletableFuture supplyAsync(Supplier supplier)
public static void supplyAsync() throws ExecutionException, InterruptedException {log.info("主線程start……");CompletableFuture<Integer> supplyAsync = CompletableFuture.supplyAsync(() -> {log.info("子線程future線程start……");int i = 10 / 2;log.info("線程名稱:{},線程執(zhí)行結果:{}", Thread.currentThread().getName(), i);log.info("子線程future線程end……");return i;});supplyAsync.get();log.info("主線程end……"); }public static CompletableFuture supplyAsync(Supplier supplier, Executor executor)
public static void supplyAsync() throws ExecutionException, InterruptedException {log.info("主線程start……");CompletableFuture<Integer> supplyAsync = CompletableFuture.supplyAsync(() -> {log.info("子線程future線程start……");int i = 10 / 2;log.info("線程名稱:{},線程執(zhí)行結果:{}", Thread.currentThread().getName(), i);log.info("子線程future線程end……");return i;},threadPool);supplyAsync.get();log.info("主線程end……"); }/*** 線程池對象*/ public static ThreadPoolExecutor threadPool = new ThreadPoolExecutor(Runtime.getRuntime().availableProcessors(),Runtime.getRuntime().availableProcessors() + 1,3,TimeUnit.SECONDS,new LinkedBlockingQueue<Runnable>(3),Executors.defaultThreadFactory(),new ThreadPoolExecutor.CallerRunsPolicy());thenRun
/*** 第一步執(zhí)行完執(zhí)行第二步,第二步的不關心第一執(zhí)行的結果* <p>* 5. thenRun* 5.1 public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)* 5.2 public CompletableFuture<Void> thenRun(Runnable action) 不關心返回值,也不關心也行結果,只有順序,1執(zhí)行后*/ public static void main(String[] args) throws Exception {// 1.public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)// 2.public CompletableFuture<Void> thenRun(Runnable action) 不關心返回值,也不關心也行結果,只有順序,1執(zhí)行后2才會執(zhí)行CompletableFuture<Void> thenRun = CompletableFuture.supplyAsync(() -> {int i = 10 / 2;log.info("線程名稱:{},線程執(zhí)行結果:{}", Thread.currentThread().getName(), i);return i;}).thenRun(() -> {log.info("上一步執(zhí)行結束這一步才會執(zhí)行,且不關心返回值,也不關心也行結果,只有順序");});// 異步調用執(zhí)行thenRun.get();}thenApply
/*** 第一步執(zhí)行完執(zhí)行第二步,第二步的參數(shù)就是第一步返回的結果* <p>* 6. thenApply 有返回值U,也關心上一步的返回值,上一步的返回值會被當成參數(shù),參數(shù)類型為T,也是順序執(zhí)行,1執(zhí)行后執(zhí)行2* 6.1 public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)* 6.2 public <U> CompletableFuture<U> thenApply(Function<? super T,? extends U> fn);*/ public static void main(String[] args) throws Exception {// thenApply 有返回值U,也關心上一步的返回值,上一步的返回值會被當成參數(shù),參數(shù)類型為T,也是順序執(zhí)行,1執(zhí)行后執(zhí)行2// 1.public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)// 2.public <U> CompletableFuture<U> thenApply(Function<? super T,? extends U> fn);CompletableFuture<Integer> thenApply = CompletableFuture.supplyAsync(() -> {int i = 10 / 2;log.info("線程名稱:{},線程執(zhí)行結果:{}", Thread.currentThread().getName(), i);return i;}).thenApply((e) -> {return e + 2;});Integer e = thenApply.get();System.out.println("e = " + e); }thenAccept
/***第一不執(zhí)行完執(zhí)行第二步,沒有返回值,第一步的返回值為第二步的參數(shù)* supplyAsync * 1 public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)* 2 public CompletableFuture<Void> thenAccept(Consumer<? super T> action)*/ public static void main(String[] args) throws Exception {// thenAccept 沒有返回結果,關心上一步的執(zhí)行結果,上一步的執(zhí)行結果會被當成參數(shù),參數(shù) T// 1.public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)// 2.public CompletableFuture<Void> thenAccept(Consumer<? super T> action)CompletableFuture<Void> thenAccept = CompletableFuture.supplyAsync(() -> {int i = 10 / 2;log.info("線程名稱:{},線程執(zhí)行結果:{}", Thread.currentThread().getName(), i);return i;}).thenAccept(e -> {int k = e + 3;log.info("k的結果為{}", k);});// 調用異步方法thenAccept.get(); }thenCompose
/*** 1. 有返回值* 2. 順序執(zhí)行,第一步的返回結果為thenCompose的參數(shù)* 3. 允許對2個CompletionStage流水線進行操作,第一個操作完成時,將第一個的結果作為第二個參數(shù)* thenCompose* public <U> CompletableFuture<U> thenCompose(Function<? super T, ? extends CompletionStage<U>> fn)*/ public static void main(String[] args) throws Exception {// thenCompose// public <U> CompletableFuture<U> thenCompose(Function<? super T, ? extends CompletionStage<U>> fn)// 第一次執(zhí)行CompletableFuture<Integer> thenCompose = CompletableFuture.supplyAsync(() -> {int i = 10 / 2;log.info("線程名稱:{},線程執(zhí)行結果:{}", Thread.currentThread().getName(), i);return i;}).thenCompose(new Function<Integer, CompletionStage<Integer>>() {@Overridepublic CompletionStage<Integer> apply(Integer i) {// 第二次執(zhí)行CompletableFuture<Integer> supplyAsync = CompletableFuture.supplyAsync(() -> {int j = i + 2;log.info("線程名稱:{},線程執(zhí)行結果:{}", Thread.currentThread().getName(), j);return j;});return supplyAsync;}});// 調用異步Integer integer = thenCompose.get();System.out.println("integer = " + integer); }thenCombine(and聚合)
/*** 1. 聚合and* 2. 有返回值 會把兩個任務都執(zhí)行完畢后,回將兩個結果都交給thenCombine去處理* 3. thenAcceptBoth(沒有返回值)與 thenCombine(有返回值)的區(qū)別* <p>* thenCombine* public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)* public <U,V> CompletableFuture<V> thenCombine( CompletionStage<? extends U> other, BiFunction<? super T,? super U,? extends V> fn)*/ public static void main(String[] args) throws ExecutionException, InterruptedException {// 聚合and// 有返回值 會把兩個任務都執(zhí)行完畢后,回將兩個結果都交給thenCombine去處理// public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)// public <U,V> CompletableFuture<V> thenCombine( CompletionStage<? extends U> other, BiFunction<? super T,? super U,? extends V> fn)// 第一個執(zhí)行CompletableFuture<Integer> f1 = CompletableFuture.supplyAsync(() -> {int i = 10 / 2;return i;});// 第二個執(zhí)行CompletableFuture<Integer> f2 = CompletableFuture.supplyAsync(() -> {int i = 10 / 3;return i;});// thenCombine 合并操作CompletableFuture<Integer> thenCombine = f1.thenCombine(f2, (x, y) -> {log.info("x為第一個執(zhí)行結果:{}", x);log.info("y為第二個執(zhí)行結果:{}", y);return x + y;});// 調用異步方法Integer integer = thenCombine.get();System.out.println("最終結果 = " + integer);}thenAcceptBoth(and聚合)
/*** 1. 聚合and* 2. 沒有返回值 會把兩個任務都執(zhí)行完畢后,回將兩個結果都交給thenAcceptBoth去處理* 3. thenAcceptBoth(沒有返回值)與 thenCombine(有返回值)的區(qū)別* thenAcceptBoth* public <U> CompletableFuture<Void> thenAcceptBoth( CompletionStage<? extends U> other, BiConsumer<? super T, ? super U> action);*/ public static void main(String[] args) throws Exception {// public <U> CompletableFuture<Void> thenAcceptBoth( CompletionStage<? extends U> other, BiConsumer<? super T, ? super U> action)// 第一個執(zhí)行CompletableFuture<Integer> f1 = CompletableFuture.supplyAsync(() -> {int i = 10 / 2;return i;});// 第二個執(zhí)行CompletableFuture<Integer> f2 = CompletableFuture.supplyAsync(() -> {int i = 10 / 3;return i;});// thenAcceptBoth 合并操作 ,沒有返回值CompletableFuture<Void> acceptBoth = f1.thenAcceptBoth(f2, (x, y) -> {log.info("x為第一個執(zhí)行結果:{}", x);log.info("y為第二個執(zhí)行結果:{}", y);});// 調用異步方法acceptBoth.get(); }runAfterBoth(and聚合)
/*** 9.runAfterBoth* 9.1 聚合and* 9.2沒有返回值,* 9.3當有連個任務時,兩個任務都執(zhí)行完,在執(zhí)行下一個任務* public CompletableFuture<Void> runAfterBoth(CompletionStage<?> other,Runnable action);*/ public static void main(String[] args) throws ExecutionException, InterruptedException {// public CompletableFuture<Void> runAfterBoth(CompletionStage<?> other,Runnable action);// 第一個執(zhí)行CompletableFuture<Integer> f1 = CompletableFuture.supplyAsync(() -> {int i = 10 / 2;return i;});// 第二個執(zhí)行CompletableFuture<Integer> f2 = CompletableFuture.supplyAsync(() -> {int i = 10 / 3;return i;});// thenAcceptBoth 合并操作 ,沒有返回值CompletableFuture<Void> afterBoth = f1.runAfterBoth(f2, () -> {log.info("第一個和第二個執(zhí)行完,接下來的業(yè)務");});// 調用異步方法afterBoth.get(); }applyToEither(or聚合)
/*** 10. applyToEither* 10.1 聚合 or* 10.2 有返回值* 10.2 針對2個CompletionStage,將計算速度最快的那個CompletionStage的結果作為下一步的處理* public <U> CompletableFuture<U> applyToEither(CompletionStage<? extends T> other, Function<? super T, U> fn);*/ public static void main(String[] args) throws ExecutionException, InterruptedException {// public <U> CompletableFuture<U> applyToEither(CompletionStage<? extends T> other, Function<? super T, U> fn);// 第一個執(zhí)行CompletableFuture<Integer> f1 = CompletableFuture.supplyAsync(() -> {int i = 10 / 5;log.info("第一個執(zhí)行結果{}",i);return i;});// 第二個執(zhí)行CompletableFuture<Integer> f2 = CompletableFuture.supplyAsync(() -> {int i = 10 / 2;log.info("第二個執(zhí)行結果{}",i);return i;});// 將計算速度最快的那個CompletionStage的結果進行處理CompletableFuture<Integer> applyToEither = f1.applyToEither(f2, res -> {int i = res + 5;return i;});Integer integer = applyToEither.get();System.out.println("integer = " + integer); }exceptionally(異常處理)
/*** 11.exceptionally* 11.1 異常處理* 11.2 有返回值* 簡單理解 就是當程序執(zhí)行錯誤進入exceptionally方法* public CompletableFuture<T> exceptionally( Function<Throwable, ? extends T> fn)** @param args*/ public static void main(String[] args) throws ExecutionException, InterruptedException {CompletableFuture<Integer> exceptionally = CompletableFuture.supplyAsync(() -> {int i = 10 / 0;return i;}).exceptionally(e -> {log.info("當執(zhí)行拋出異常進入此方法,異常信息:{}", e.getMessage());return null;});Integer integer = exceptionally.get();System.out.println("integer = " + integer); }whenComplete(異常處理)
/*** 11.whenComplete* 可以獲取到上一次的返回結果* public CompletableFuture<T> whenComplete(BiConsumer<? super T, ? super Throwable> action)*/ public static void main(String[] args) throws ExecutionException, InterruptedException {//CompletableFuture<Integer> whenComplete = CompletableFuture.supplyAsync(() -> {int i = 10 / 5;return i;}).whenComplete((t, e) -> {log.info("上一步的執(zhí)行結果{}", t);if (t > 0) {System.out.println("t 大于 0,結果為: " + t);}});Integer integer = whenComplete.get();System.out.println("integer = " + integer); }handle(異常處理)
/*** 13. handle* 有返回值* 相當于 try()finally() ,可以對執(zhí)行結果進行處理,也可以對異常信息進行處理* public <U> CompletableFuture<U> handle( BiFunction<? super T, Throwable, ? extends U> fn)*/ public static void main(String[] args) throws ExecutionException, InterruptedException {//CompletableFuture<Integer> handle = CompletableFuture.supplyAsync(() -> {int i = 10 / 0;return i;}).handle((t, e) -> {log.info("上一步的執(zhí)行結果{}", t);int res = 0;if (e != null) {log.info("異常信息{}", e.getMessage());return null;}if (t != null) {res = t + 1;}return res;});Integer integer = handle.get();System.out.println("integer = " + integer); }所有代碼
import lombok.extern.slf4j.Slf4j; import org.apache.tomcat.jni.User;import java.util.concurrent.*; import java.util.function.Function;/*** 異步編排*/ @Slf4j public class AsyFutureDemo {/*** 1.runAsync 沒有返回值* 2.1 public static CompletableFuture<Void> runAsync(Runnable runnable); 使用默認的線程池* 2.2 public static CompletableFuture<Void> runAsync(Runnable runnable, Executor executor) 自定義線程池* <p>* 2.supplyAsync: 有返回值的,關注返回值* 2.1 public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier) 使用默認的線程池* 2.3 public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier, Executor executor) 自定義線程池* <p>* 3. thenRun 第一步執(zhí)行完執(zhí)行第二步,第二步的不關心第一執(zhí)行的結果* 3.1 public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)* 3.2 public CompletableFuture<Void> thenRun(Runnable action) 不關心返回值,也不關心也行結果,只有順序,1執(zhí)行后2才會執(zhí)行* <p>* 4. thenApply 有返回值U,也關心上一步的返回值,上一步的返回值會被當成參數(shù),參數(shù)類型為T,也是順序執(zhí)行,1執(zhí)行后執(zhí)行2* 4.1 public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)* 4.2 public <U> CompletableFuture<U> thenApply(Function<? super T,? extends U> fn);* <p>* 5. thenAccept 沒有返回結果,關心上一步的執(zhí)行結果,上一步的執(zhí)行結果會被當成參數(shù),參數(shù) T* 5.1 public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)* 5.2 public CompletableFuture<Void> thenAccept(Consumer<? super T> action)* <p>* 6. thenCompose 有返回值,順序執(zhí)行,第一步的返回結果為thenCompose的參數(shù),允許對2個CompletionStage流水線進行操作,第一個操作完成時,將第一個的結果作為第二個參數(shù)* public <U> CompletableFuture<U> thenCompose(Function<? super T, ? extends CompletionStage<U>> fn)* <p>* 7.thenCombine* 7.1 聚合and,有返回值 當* 7.2 把兩個任務都執(zhí)行完畢后,會將兩個結果都交給thenCombine去處理* 7.3 thenAcceptBoth(沒有返回值)與 thenCombine(有返回值)的區(qū)別* public <U,V> CompletableFuture<V> thenCombine( CompletionStage<? extends U> other, BiFunction<? super T,? super U,? extends V> fn)* <p>* 8.thenAcceptBoth* 8.1 聚合and* 8.2 沒有返回值 會把兩個任務都執(zhí)行完畢后,回將兩個結果都交給thenAcceptBoth去處理* public <U> CompletableFuture<Void> thenAcceptBoth( CompletionStage<? extends U> other, BiConsumer<? super T, ? super U> action)* <p>* 9.runAfterBoth* 9.1 聚合and* 9.2沒有返回值,* 9.3當有連個任務時,兩個任務都執(zhí)行完,在執(zhí)行下一個任務* public CompletableFuture<Void> runAfterBoth(CompletionStage<?> other,Runnable action);* <p>* 10. applyToEither* 10.1 聚合 or* 10.2 有返回值* 10.2 針對2個CompletionStage,將計算速度最快的那個CompletionStage的結果作為下一步的處理* public <U> CompletableFuture<U> applyToEither(CompletionStage<? extends T> other, Function<? super T, U> fn);* <p>* 11.exceptionally* 11.1 異常處理* 11.2 有返回值* 簡單理解 就是當程序執(zhí)行錯誤進入exceptionally方法* public CompletableFuture<T> exceptionally( Function<Throwable, ? extends T> fn)* <p>* 12.whenComplete* 可以獲取到上一次的返回結果* public CompletableFuture<T> whenComplete(BiConsumer<? super T, ? super Throwable> action)* <p>* 13. handle* 有返回值* 相當于 try()finally() ,可以對執(zhí)行結果進行處理,也可以對異常信息進行處理* public <U> CompletableFuture<U> handle( BiFunction<? super T, Throwable, ? extends U> fn)*//*** 13. handle* 有返回值* 相當于 try()finally() ,可以對執(zhí)行結果進行處理,也可以對異常信息進行處理* public <U> CompletableFuture<U> handle( BiFunction<? super T, Throwable, ? extends U> fn)*/public static void main(String[] args) throws ExecutionException, InterruptedException {//CompletableFuture<Integer> handle = CompletableFuture.supplyAsync(() -> {int i = 10 / 0;return i;}).handle((t, e) -> {log.info("上一步的執(zhí)行結果{}", t);int res = 0;if (e != null) {log.info("異常信息{}", e.getMessage());return null;}if (t != null) {res = t + 1;}return res;});Integer integer = handle.get();System.out.println("integer = " + integer);}/*** 12.whenComplete* 可以獲取到上一次的返回結果* public CompletableFuture<T> whenComplete(BiConsumer<? super T, ? super Throwable> action)*/public static void whenComplete() throws ExecutionException, InterruptedException {//CompletableFuture<Integer> whenComplete = CompletableFuture.supplyAsync(() -> {int i = 10 / 5;return i;}).whenComplete((t, e) -> {log.info("上一步的執(zhí)行結果{}", t);if (t > 0) {System.out.println("t 大于 0,結果為: " + t);}});Integer integer = whenComplete.get();System.out.println("integer = " + integer);}/*** 11.exceptionally* 11.1 異常處理* 11.2 有返回值* 簡單理解 就是當程序執(zhí)行錯誤進入exceptionally方法* public CompletableFuture<T> exceptionally( Function<Throwable, ? extends T> fn)*/public static void exceptionally() throws ExecutionException, InterruptedException {CompletableFuture<Integer> exceptionally = CompletableFuture.supplyAsync(() -> {int i = 10 / 0;return i;}).exceptionally(e -> {log.info("當執(zhí)行拋出異常進入此方法,異常信息:{}", e.getMessage());return null;});Integer integer = exceptionally.get();System.out.println("integer = " + integer);}/*** 10. applyToEither* 10.1 聚合 or* 10.2 有返回值* 10.2 針對2個CompletionStage,將計算速度最快的那個CompletionStage的結果作為下一步的處理* public <U> CompletableFuture<U> applyToEither(CompletionStage<? extends T> other, Function<? super T, U> fn);*/public static void applyToEither() throws ExecutionException, InterruptedException {// public <U> CompletableFuture<U> applyToEither(CompletionStage<? extends T> other, Function<? super T, U> fn);// 第一個執(zhí)行CompletableFuture<Integer> f1 = CompletableFuture.supplyAsync(() -> {int i = 10 / 5;log.info("第一個執(zhí)行結果{}", i);return i;});// 第二個執(zhí)行CompletableFuture<Integer> f2 = CompletableFuture.supplyAsync(() -> {int i = 10 / 2;log.info("第二個執(zhí)行結果{}", i);return i;});// 將計算速度最快的那個CompletionStage的結果進行處理CompletableFuture<Integer> applyToEither = f1.applyToEither(f2, res -> {int i = res + 5;return i;});Integer integer = applyToEither.get();System.out.println("integer = " + integer);}/*** 9.runAfterBoth* 9.1 聚合and* 9.2沒有返回值,* 9.3當有連個任務時,兩個任務都執(zhí)行完,在執(zhí)行下一個任務* public CompletableFuture<Void> runAfterBoth(CompletionStage<?> other,Runnable action);*/public static void runAfterBoth() throws ExecutionException, InterruptedException {// public CompletableFuture<Void> runAfterBoth(CompletionStage<?> other,Runnable action);// 第一個執(zhí)行CompletableFuture<Integer> f1 = CompletableFuture.supplyAsync(() -> {int i = 10 / 2;return i;});// 第二個執(zhí)行CompletableFuture<Integer> f2 = CompletableFuture.supplyAsync(() -> {int i = 10 / 3;return i;});// thenAcceptBoth 合并操作 ,沒有返回值CompletableFuture<Void> afterBoth = f1.runAfterBoth(f2, () -> {log.info("第一個和第二個執(zhí)行完,接下來的業(yè)務");});// 調用異步方法afterBoth.get();}/*** 1. 聚合and* 2. 沒有返回值 會把兩個任務都執(zhí)行完畢后,回將兩個結果都交給thenAcceptBoth去處理* 3. thenAcceptBoth(沒有返回值)與 thenCombine(有返回值)的區(qū)別* thenAcceptBoth* public <U> CompletableFuture<Void> thenAcceptBoth( CompletionStage<? extends U> other, BiConsumer<? super T, ? super U> action);*/public static void thenAcceptBoth() throws Exception {// public <U> CompletableFuture<Void> thenAcceptBoth( CompletionStage<? extends U> other, BiConsumer<? super T, ? super U> action)// 第一個執(zhí)行CompletableFuture<Integer> f1 = CompletableFuture.supplyAsync(() -> {int i = 10 / 2;return i;});// 第二個執(zhí)行CompletableFuture<Integer> f2 = CompletableFuture.supplyAsync(() -> {int i = 10 / 3;return i;});// thenAcceptBoth 合并操作 ,沒有返回值CompletableFuture<Void> acceptBoth = f1.thenAcceptBoth(f2, (x, y) -> {log.info("x為第一個執(zhí)行結果:{}", x);log.info("y為第二個執(zhí)行結果:{}", y);});// 調用異步方法acceptBoth.get();}/*** 1. 聚合and* 2. 有返回值 會把兩個任務都執(zhí)行完畢后,回將兩個結果都交給thenCombine去處理* 3. thenAcceptBoth(沒有返回值)與 thenCombine(有返回值)的區(qū)別* <p>* thenCombine* public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)* public <U,V> CompletableFuture<V> thenCombine( CompletionStage<? extends U> other, BiFunction<? super T,? super U,? extends V> fn)*/public static void thenCombine() throws ExecutionException, InterruptedException {// 聚合and// 有返回值 會把兩個任務都執(zhí)行完畢后,回將兩個結果都交給thenCombine去處理// public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)// public <U,V> CompletableFuture<V> thenCombine( CompletionStage<? extends U> other, BiFunction<? super T,? super U,? extends V> fn)// 第一個執(zhí)行CompletableFuture<Integer> f1 = CompletableFuture.supplyAsync(() -> {int i = 10 / 2;return i;});// 第二個執(zhí)行CompletableFuture<Integer> f2 = CompletableFuture.supplyAsync(() -> {int i = 10 / 3;return i;});// thenCombine 合并操作CompletableFuture<Integer> thenCombine = f1.thenCombine(f2, (x, y) -> {log.info("x為第一個執(zhí)行結果:{}", x);log.info("y為第二個執(zhí)行結果:{}", y);return x + y;});// 調用異步方法Integer integer = thenCombine.get();System.out.println("最終結果 = " + integer);}/*** 1. 有返回值* 2. 順序執(zhí)行,第一步的返回結果為thenCompose的參數(shù)* 3. 允許對2個CompletionStage流水線進行操作,第一個操作完成時,將第一個的結果作為第二個參數(shù)* thenCompose* public <U> CompletableFuture<U> thenCompose(Function<? super T, ? extends CompletionStage<U>> fn)*/public static void thenCompose(String[] args) throws Exception {// thenCompose// public <U> CompletableFuture<U> thenCompose(Function<? super T, ? extends CompletionStage<U>> fn)// 第一次執(zhí)行CompletableFuture<Integer> thenCompose = CompletableFuture.supplyAsync(() -> {int i = 10 / 2;log.info("線程名稱:{},線程執(zhí)行結果:{}", Thread.currentThread().getName(), i);return i;}).thenCompose(new Function<Integer, CompletionStage<Integer>>() {@Overridepublic CompletionStage<Integer> apply(Integer i) {// 第二次執(zhí)行CompletableFuture<Integer> supplyAsync = CompletableFuture.supplyAsync(() -> {int j = i + 2;log.info("線程名稱:{},線程執(zhí)行結果:{}", Thread.currentThread().getName(), j);return j;});return supplyAsync;}});// 調用異步Integer integer = thenCompose.get();System.out.println("integer = " + integer);}/*** 第一不執(zhí)行完執(zhí)行第二步,沒有返回值,第一步的返回值為第二步的參數(shù)* 7. supplyAsync* 7.1 public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)* 7.2 public CompletableFuture<Void> thenAccept(Consumer<? super T> action)*/public static void thenAccept(String[] args) throws Exception {// thenAccept 沒有返回結果,關心上一步的執(zhí)行結果,上一步的執(zhí)行結果會被當成參數(shù),參數(shù) T// 1.public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)// 2.public CompletableFuture<Void> thenAccept(Consumer<? super T> action)CompletableFuture<Void> thenAccept = CompletableFuture.supplyAsync(() -> {int i = 10 / 2;log.info("線程名稱:{},線程執(zhí)行結果:{}", Thread.currentThread().getName(), i);return i;}).thenAccept(e -> {int k = e + 3;log.info("k的結果為{}", k);});// 調用異步方法thenAccept.get();}/*** 第一步執(zhí)行完執(zhí)行第二步,第二步的參數(shù)就是第一步返回的結果* <p>* 6. thenApply 有返回值U,也關心上一步的返回值,上一步的返回值會被當成參數(shù),參數(shù)類型為T,也是順序執(zhí)行,1執(zhí)行后執(zhí)行2* 6.1 public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)* 6.2 public <U> CompletableFuture<U> thenApply(Function<? super T,? extends U> fn);*/public static void thenApply() throws Exception {// thenApply 有返回值U,也關心上一步的返回值,上一步的返回值會被當成參數(shù),參數(shù)類型為T,也是順序執(zhí)行,1執(zhí)行后執(zhí)行2// 1.public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)// 2.public <U> CompletableFuture<U> thenApply(Function<? super T,? extends U> fn);CompletableFuture<Integer> thenApply = CompletableFuture.supplyAsync(() -> {int i = 10 / 2;log.info("線程名稱:{},線程執(zhí)行結果:{}", Thread.currentThread().getName(), i);return i;}).thenApply((e) -> {return e + 2;});Integer e = thenApply.get();System.out.println("e = " + e);}/*** 第一步執(zhí)行完執(zhí)行第二步,第二步的不關心第一執(zhí)行的結果* <p>* 5. thenRun* 5.1 public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)* 5.2 public CompletableFuture<Void> thenRun(Runnable action) 不關心返回值,也不關心也行結果,只有順序,1執(zhí)行后2才會執(zhí)行*/public static void thenRun() throws Exception {// 1.public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)// 2.public CompletableFuture<Void> thenRun(Runnable action) 不關心返回值,也不關心也行結果,只有順序,1執(zhí)行后2才會執(zhí)行CompletableFuture<Void> thenRun = CompletableFuture.supplyAsync(() -> {int i = 10 / 2;log.info("線程名稱:{},線程執(zhí)行結果:{}", Thread.currentThread().getName(), i);return i;}).thenRun(() -> {log.info("上一步執(zhí)行結束這一步才會執(zhí)行,且不關心返回值,也不關心也行結果,只有順序");});// 異步調用執(zhí)行thenRun.get();}/*** public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier) 使用默認的線程池* public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier, Executor executor) 自定義線程池*/public static void supplyAsync() throws ExecutionException, InterruptedException {log.info("主線程start……");CompletableFuture<Integer> supplyAsync = CompletableFuture.supplyAsync(() -> {log.info("子線程future線程start……");int i = 10 / 2;log.info("線程名稱:{},線程執(zhí)行結果:{}", Thread.currentThread().getName(), i);log.info("子線程future線程end……");return i;}, threadPool);supplyAsync.get();log.info("主線程end……");}/*** 線程池對象*/public static ThreadPoolExecutor threadPool = new ThreadPoolExecutor(Runtime.getRuntime().availableProcessors(),Runtime.getRuntime().availableProcessors() + 1,3,TimeUnit.SECONDS,new LinkedBlockingQueue<Runnable>(3),Executors.defaultThreadFactory(),new ThreadPoolExecutor.CallerRunsPolicy());/*** 1.public static CompletableFuture<Void> runAsync(Runnable runnable); 使用默認的線程池* 只需將 ,threadPool 去掉即可* 2.public static CompletableFuture<Void> runAsync(Runnable runnable, Executor executor) 自定義線程池* 只需將 ,threadPool 加上即可*/public static void runAsync() throws ExecutionException, InterruptedException {log.info("主線程start……");/*** 異步任務* 沒有返回值,為定義線程池* public static CompletableFuture<Void> runAsync(Runnable runnable);*/CompletableFuture<Void> runAsync = CompletableFuture.runAsync(() -> {log.info("子線程future線程start……");int i = 10 / 2;log.info("線程名稱:{},線程執(zhí)行結果:{}", Thread.currentThread().getName(), i);log.info("子線程future線程end……");}, threadPool);// 調用異步任務runAsync.get();log.info("主線程end……");}/*** supplyAsync*//*** 異步調用* 異步調用實現(xiàn)一個不需要被等等的方法的返回值,讓調用者繼續(xù)執(zhí)行(異步執(zhí)行);* 在java 中,簡單的講就是開啟另一個線程完成程序計算,使得調用者繼續(xù)執(zhí)行,不需要等等計算的結果,但是調用者任然需要獲取線程的計算結果(不需要同步阻塞等待)。* 通俗理解就是:* 主線程將任務交個子線程,主線程就返回,不需要等待執(zhí)行結果,主線程可以繼續(xù)往下執(zhí)行*//*** Future 也是一個異步計算結果返回接口,目的獲取返回值結果。但是 future 在獲取返回值結構的時候,方法必須同步阻塞等待返回值結果。* Get : 獲取結果(等待,阻塞)* Get(timeout) : 獲取結果,指定等待時間* Cancel : 取消當前任務* isDone : 判斷任務是否已經(jīng)完成 (輪詢)* futrure 對于結果獲取不是很方便,只能通過同步阻塞的方式獲取結果,或者是輪詢的方式獲取到結果;阻塞的方式獲取返回值結果與異步的思想想違背,輪詢方式又很占用 cpu 資源,也不能及時得到我們結果。*//*** CompletableFuture* 可以幫助我們簡化異步編程復雜性,提供了函數(shù)式編程的能力,可以通過回調函數(shù)的方式處理計算結果。* public class CompletableFuture<T> implements Future<T>, CompletionStage<T>* CompletableFuture 具有Future 的特性,還實現(xiàn)了CompletionStage 接口,具備CompletionStage* 接口的特性: 串行執(zhí)行,并行執(zhí)行,聚合(AND 聚合,OR 聚合)* 1.串行關系執(zhí)行* then – 然后,也就是表示下一步,所以通常是一個串行的關系體現(xiàn),then后面的單詞(比如 run/apply/accept)就是函數(shù)是接口中抽象方法名稱;* 利用上一步的執(zhí)行結果,去進行下一步任務執(zhí)行,任務執(zhí)行具有先后順序,因此把這種操作叫做串行關系** public CompletionStage<Void> thenRun(Runnable action);* public CompletionStage<Void> thenRunAsync(Runnable action);* public CompletableFuture<Void> thenRunAsync(Runnable action,Executor executor);** public <U> CompletableFuture<U> thenApply( Function<? super T,? extends U> fn) ;* public <U> CompletionStage<U> thenApplyAsync(Function<? super T,? extends U> fn);* public <U> CompletionStage<U> thenApplyAsync(Function<? super T,? extends U> fn,Executor executor);** public CompletionStage<Void> thenAccept(Consumer<? super T> action);* public CompletionStage<Void> thenAcceptAsync(Consumer<? super T> action);* public CompletionStage<Void> thenAcceptAsync(Consumer<? super T> action, Executor executor);** public <U> CompletionStage<U> thenCompose(Function<? super T, ? extends CompletionStage<U>> fn);* public <U> CompletionStage<U> thenComposeAsync(Function<? super T, ? extends CompletionStage<U>> fn);* public <U> CompletionStage<U> thenComposeAsync(Function<? super T, ? extends CompletionStage<U>> fn, Executor executor);** 2.聚合and* Combine…… with …… 和 both…… and …… 都是要求兩者都必須滿足,也就是and 且的關系。** public <U,V> CompletionStage<V> thenCombine (CompletionStage<? extends U> other, BiFunction<? super T,? super U,? extends V> fn);* public <U,V> CompletionStage<V> thenCombineAsync (CompletionStage<? extends U> other, BiFunction<? super T,? super U,? extends V> fn);* public <U,V> CompletionStage<V> thenCombineAsync (CompletionStage<? extends U> other, BiFunction<? super T,? super U,? extends V> fn, Executor executor);** public <U> CompletionStage<Void> thenAcceptBoth (CompletionStage<? extends U> other, BiConsumer<? super T, ? super U> action);* public <U> CompletionStage<Void> thenAcceptBothAsync (CompletionStage<? extends U> other, BiConsumer<? super T, ? super U> action);* public <U> CompletionStage<Void> thenAcceptBothAsync(CompletionStage<? extends U> other, BiConsumer<? super T, ? super U> action, Executor executor);** public CompletionStage<Void> runAfterBoth(CompletionStage<?> other, Runnable action);* public CompletionStage<Void> runAfterBothAsync(CompletionStage<?> other, Runnable action);* public CompletionStage<Void> runAfterBothAsync(CompletionStage<?> other, Runnable action, Executor executor);** 3.聚合or* public <U> CompletionStage<U> applyToEitherAsync (CompletionStage<? extends T> other, Function<? super T, U> fn);* public <U> CompletionStage<U> applyToEitherAsync (CompletionStage<? extends T> other, Function<? super T, U> fn, Executor executor);** public <U> CompletionStage<U> applyToEitherAsync (CompletionStage<? extends T> other, Function<? super T, U> fn);* public <U> CompletionStage<U> applyToEitherAsync (CompletionStage<? extends T> other, Function<? super T, U> fn, Executor executor);* public CompletionStage<Void> acceptEither (CompletionStage<? extends T> other, Consumer<? super T> action);** public CompletionStage<Void> acceptEitherAsync (CompletionStage<? extends T> other, Consumer<? super T> action);* public CompletionStage<Void> acceptEitherAsync (CompletionStage<? extends T> other, Consumer<? super T> action, Executor executor);* public CompletionStage<Void> runAfterEither(CompletionStage<?> other, Runnable action);* public CompletionStage<Void> runAfterEitherAsync (CompletionStage<?> other, Runnable action);* public CompletionStage<Void> runAfterEitherAsync (CompletionStage<?> other, Runnable action, Executor executor);** 4.異常處理* public CompletionStage<T> exceptionally(Function<Throwable, ? extends T> fn);* public CompletionStage<T> whenComplete (BiConsumer<? super T, ? super Throwable> action);* public CompletionStage<T> whenCompleteAsync (BiConsumer<? super T, ? super Throwable> action);* public CompletionStage<T> whenCompleteAsync (BiConsumer<? super T, ? super Throwable> action, Executor executor);* public <U> CompletionStage<U> handle (BiFunction<? super T, Throwable, ? extends U> fn);* public <U> CompletionStage<U> handleAsync (BiFunction<? super T, Throwable, ? extends U> fn);* public <U> CompletionStage<U> handleAsync (BiFunction<? super T, Throwable, ? extends U> fn, Executor executor);**//*** 異步開啟* CompletableFuture 提供了 4 個靜態(tài)的方法,來創(chuàng)建一個異步操作(異步開啟: 從這 4 個靜態(tài)的方法開發(fā)即可)* 1.runAsync方法:* 沒有返回值的方法,不關注返回值* public static CompletableFuture<Void> runAsync(Runnable runnable);* public static CompletableFuture<Void> runAsync(Runnable runnable,Executor executor);* 2.supplyAsync :* 有返回值,關注返回值的。* public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier);* public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier,Executor executor)*/ }網(wǎng)上找的參考Demo
@Autowiredprivate ThreadPoolExecutor executor;// 新建一個包裝類對象SkuItemVo itemVo = new SkuItemVo();// 開啟異步編排實現(xiàn),提升服務性能 supplyAsync 有返回值// 1、根據(jù) skuId 查詢 sku 基本信息CompletableFuture<SkuInfoEntity> infoFuture =CompletableFuture.supplyAsync(() -> {SkuInfoEntity skuInfoEntity = this.getById(skuId);itemVo.setInfo(skuInfoEntity);return skuInfoEntity;}, executor);// 2、根據(jù) skuId 查詢 sku 圖片信息(多個圖片),skuId 是外鍵 runAsync 沒有返回值CompletableFuture<Void> imagesFuture =CompletableFuture.runAsync(() -> {List<SkuImagesEntity> imageList =skuImagesService.list(newQueryWrapper<SkuImagesEntity>().eq("sku_id", skuId));itemVo.setImages(imageList);}, executor);//3、根據(jù) spuID 獲取 spu 的銷售屬性 (thenAcceptAsync 串行,沒有返回值)CompletableFuture<Void> salesFuture =infoFuture.thenAcceptAsync((res) -> {// 獲取 sku 與之對應的 spuIdLong spuId = res.getSpuId();List<SkuItemSaleAttrVo> saleAttrVos =skuSaleAttrValueService.getSaleAttrs(spuId);if (saleAttrVos.size() > 0 && saleAttrVos != null) {itemVo.setAttrSales(saleAttrVos);}}, executor);//4、根據(jù) spuId 查詢 spu 的描述信息 (thenAcceptAsync 串行,沒有返回值)CompletableFuture<Void> descFuture =infoFuture.thenAcceptAsync((res) -> {// 獲取 sku 與之對應的 spuIdLong spuId = res.getSpuId();SpuInfoDescEntity spuInfoDescEntity =spuInfoDescService.getOne(new QueryWrapper<SpuInfoDescEntity>().eq("spu_id", spuId));if (spuInfoDescEntity != null) {itemVo.setDesc(spuInfoDescEntity);}}, executor);//5、根據(jù) spuID,categoryId 查詢 sku 分組規(guī)格參數(shù)屬性值 (thenAcceptAsync 串行,沒有返回值)CompletableFuture<Void> groupFuture =infoFuture.thenAcceptAsync((res) -> {// 獲取 sku 與之對應的 spuIdLong spuId = res.getSpuId();// 獲取分類 idLong categoryId = res.getCategoryId();List<SpuAttrGroupVo> attrGroupVos =attrGroupService.getGroupAttr(spuId, categoryId);if (attrGroupVos.size() > 0) {itemVo.setAttrGroups(attrGroupVos);}}, executor);// 等待所有的任務完成后,才能返回結果 try{CompletableFuture.allOf(infoFuture, imagesFuture, salesFuture, descFuture, groupFuture).get();catch (Exception e) {e.printStackTrace();}總結
- 上一篇: MSU 出品的 H 264 编码器比较
- 下一篇: mpg格式转换为mp4格式