詳解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!

推薦閱讀: