詳解Java CompletableFuture使用方法以及與FutureTask的區別
總的來說簡潔瞭FutureTask與線程池的配合使用
沒啥太大區別吧我覺得, 使用方法不一樣, 多瞭一些方法 ???
futureTask 創建異步任務
FutureTask<String> stringFutureTask = new FutureTask<>(() -> { return "aa"; }); executorService.execute(stringFutureTask); System.out.println(stringFutureTask.get()); CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> { return "aa"; }, executorService); // 不用手動提交瞭 System.out.println(future1.get());
還有很多異步回調, 組合處理
創建任務
1. .supplyAsync
創建一個帶返回值的任務
2. .runAsync
創建一個不帶返回值的任務
ExecutorService executorService = Executors.newFixedThreadPool(1); // 帶返回值 CompletableFuture future = CompletableFuture.supplyAsync(() -> { try { System.out.println("future " + new Date()); Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } return "aaa"; }, executorService); // 推薦使用
以上兩個方法都有兩個構造方法, 默認不指定自定義線程池, 他會指定默認的提交任務的方法
// 查看cpu的核數是否大於1核 private static final boolean useCommonPool = (ForkJoinPool.getCommonPoolParallelism() > 1); // 如果大於1核 則調用execute方法, 每次創建一個線程 private static final Executor asyncPool = useCommonPool ? ForkJoinPool.commonPool() : new ThreadPerTaskExecutor(); static final class ThreadPerTaskExecutor implements Executor { public void execute(Runnable r) { new Thread(r).start(); } }
所以推薦自定義線程池的方式
異步回調
指的是 異步任務結束後調用的任務
1. .thenApply
帶返回值的異步調用函數, 有入參, 有出參
2. .thenAccept
不帶返回值的異步回調函數, 有入參
CompletableFuture future = CompletableFuture.supplyAsync(() -> { try { System.out.println("future " + new Date()); Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } return "aaa"; }, executorService); // future執行完之後執行的異步任務 CompletableFuture<String> thenApply = future.thenApply((result) -> { System.out.println("future2 " +new Date()); System.out.println(result); return "bbb" + result; });
3. .exceptionally
異步任務出現異常調用的回調方法
CompletableFuture future = CompletableFuture.supplyAsync(() -> { try { System.out.println("future " + new Date()); Thread.sleep(2000); int a = 1 / 0; } catch (InterruptedException e) { e.printStackTrace(); } return "aaa"; }, executorService); CompletableFuture<String> exceptionally = future.exceptionally((result) -> { System.out.println("future3 " + result); return "bbb" + result; }); // 出現異常則返回異常, 沒異常則返回future的返回值 System.out.println(exceptionally.get());
去掉異常
4. .whenComplete
當主任務出現異常時, 會終止任務,get的時候會拋出主任務的異常, 入參值為null, 否則正常運行
CompletableFuture future = CompletableFuture.supplyAsync(() -> { try { System.out.println("future " + new Date()); Thread.sleep(2000); int a = 1/0; } catch (InterruptedException e) { e.printStackTrace(); } return "aaa"; }, executorService); CompletableFuture<String> exceptionally = future.whenComplete((result, error) -> { System.out.println("future3 " + result); System.out.println("future3 " + error); }); System.out.println(exceptionally.get());
去掉異常
組合處理
….
就是將多個任務組合起來執行, 時間原因, 這裡我就不介紹瞭, 大傢另行百度吧
到此這篇關於詳解Java CompletableFuture使用方法的文章就介紹到這瞭,更多相關Java CompletableFuture內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- Java8 CompletableFuture runAsync學習總結submit() execute()等
- 一文搞懂Java創建線程的五種方法
- Java多線程工具CompletableFuture的使用教程
- Java異步編程工具Twitter Future詳解
- Java並行執行任務的幾種方案小結