最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java中CompletableFuture?的詳細介紹

 更新時間:2022年05月23日 09:08:23   作者:??旺財gg????  
這篇文章主要介紹了Java中的CompletableFuture,通過創(chuàng)建?CompletableFuture?的對象的工廠方法展開詳細的內(nèi)容介紹,需要的小伙伴可以參考一下

1.概述

1.0 創(chuàng)建 CompletableFuture 的對象的工廠方法

static?CompletableFuture<Void> runAsync(Runnable?runnable)
static?CompletableFuture<Void> runAsync(Runnable runnable, Executor executor)
static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)
static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier, Executor executor)

runAsync 的參數(shù)是 Runnable, 返回值是 CompletableFuture, 意思是工廠方法創(chuàng)建的 CompletableFuture 對象封裝的任務沒有返回值。

例如:

CompletableFuture<Void> run = CompletableFuture.runAsync(()-> System.out.println("hello"));

而 suppyAsync 參數(shù)類型是 Supplier,返回值是CompletableFuture<U> , 意思是任務不接受參數(shù),但是會返回結(jié)果。

CompletableFuture<String> supply = CompletableFuture.supplyAsync(() -> {
    System.out.println("Hello");
    return "hello world!"";
});
System.out.println(supply.get());  //hello world!"

所以如果任務需要返回結(jié)果,那么應該選擇 suppyAsync;否則可以選擇 runAsync。

1.1 non-async 和 async 區(qū)別

public CompletionStage<Void> thenRun(Runnable action);
public CompletionStage<Void> thenRunAsync(Runnable action);
public CompletionStage<Void> thenRunAsync(Runnable action,Executor executor);

CompletableFuture 中有眾多類似這樣的方法,那么 non-async 和 async 和版本的方法究竟有什么區(qū)別呢? 參考官方文檔的描述:

Actions supplied for dependent completions of non-async methods may be performed by the thread that completes the current CompletableFuture, or by any other caller of a completion method.

翻譯:傳遞給 non-async 方法作為參數(shù)的函數(shù)(action)可能會在完成當前的 CompletableFuture 的線程中執(zhí)行,也可能會在方法的調(diào)用者線程中執(zhí)行。

All async methods without an explicit Executor argument are performed using the ForkJoinPool.commonPool() (unless it does not support a parallelism level of at least two, in which case, a new Thread is created to run each task). To simplify monitoring, debugging, and tracking, all generated asynchronous tasks are instances of the marker interface CompletableFuture.AsynchronousCompletionTask.

翻譯:所有沒有Executor 參數(shù)的 async 方法都在 ForkJoinPool.commonPool()線程池中執(zhí)行(除非不支持最小并發(fā)度為2,這種情況下,每個任務會創(chuàng)建一個新線程去執(zhí)行)。為了簡化監(jiān)控、調(diào)試和追蹤,所有生成的異步任務都是接口 CompletableFuture.AsynchronousCompletionTask的實例。

從上面這兩段官方描述看。async 類方法比較容易理解,就是 CompletableFuture 實例的任務執(zhí)行完成后,會將 action 提交到缺省的異步線程池 ForkJoinPool.commonPool(),或者 async 類方法參數(shù)Executor executor 指定的線程池中執(zhí)行。

而對于 non-async 的描述則有點不明確。action 可能會在完成 CompletableFuture 實例任務的線程中執(zhí)行,也可能會在調(diào)用 thenRun(編排任務完成后執(zhí)行 action 的系列方法) 方法的線程中執(zhí)行。這個主要是看調(diào)用 thenRun 的時候,CompletableFuture 實例的任務是否已經(jīng)完成。如果沒有完成,那么action 會在完成任務的線程中執(zhí)行。如果任務已經(jīng)完成,則 action 會在調(diào)用thenAccept 等注冊方法的線程中執(zhí)行

1.1.1 non-async 示例:注冊 action 的時候任務可能已經(jīng)結(jié)束

@Test
void testThenRunWithTaskCompleted() throws Exception{
    CompletableFuture<Void> future = CompletableFuture.supplyAsync(new Supplier<Integer>() {
        @Override
        public Integer get() {
            System.out.println("[" + Thread.currentThread().getName() + "] " + " in task" );
            return 1;
        }
    }).thenRun(() -> {
        System.out.println("[" + Thread.currentThread().getName() + "] " + " in action" );
    });
    future.get();
}

運行結(jié)果:

[ForkJoinPool.commonPool-worker-1]  in task
[main]  in action

分析: 任務通過 CompletableFuture.supplyAsync 提交后,會以異步的方式在 ForkJoinPool.commonPool() 線程池中運行。這時候有兩個線程,一個是[ForkJoinPool.commonPool-worker-1] 執(zhí)行 Supplier.get 方法;一個是[main] 主線程提交完異步任務后,繼續(xù)調(diào)用 thenRun 編排任務完成后執(zhí)行 action。由于Supplier.get 非常簡單,幾乎立刻返回。所以很大概率在主線程調(diào)用 thenRun 編排任務完成后執(zhí)行 action的時候,異步任務已經(jīng)完成,所以 action 在主線程中執(zhí)行了。注:在筆者的電腦上幾乎100% 是這樣的調(diào)度方式。

1.1.2 non-async 示例:注冊 action 的時候任務未完成

@Test
void testThenRunWithTaskUncompleted() throws Exception{
    CompletableFuture<Void> future = CompletableFuture.supplyAsync(new Supplier<Integer>() {
        @Override
        public Integer get() {
            System.out.println("[" + Thread.currentThread().getName() + "] " + " in task" );
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return new Random().nextInt(10);
        }
    }).thenRun(() -> {
        System.out.println("[" + Thread.currentThread().getName() + "] " + " in action" );
    });
    future.get();
}

運行結(jié)果:

[ForkJoinPool.commonPool-worker-1]  in task
[ForkJoinPool.commonPool-worker-1]  in action

分析:在 Supplier.get 加入 sleep,延遲任務結(jié)束。主線程提交完異步任務后,繼續(xù)調(diào)用 thenRun 編排任務完成后執(zhí)行 action 的時候,任務沒有結(jié)束。所以這個action 在完成任務的線程中執(zhí)行。

1.2 Run 類方法

Run 類方法指 thenRun、runAfterBoth、runAfterEither 等。Run 類方法的動作參數(shù)都是Runable action。例如 thenRun(Runnable action)。這就意味著這個 action 不關心任務的結(jié)果,action 本身也沒有返回值。只是為了實現(xiàn)在完成任務后執(zhí)行一個動作的目的。

1.3 Accept 類方法

Accept 類方法指 thenAccept、runAcceptBoth、runAcceptEither 等。Accept 類方法的動作參數(shù)都是Consumer<? super T> action。例如 thenAccept(Consumer<? super T> action)。如方法名和參數(shù)所示,action 是接受并消費任務結(jié)果的消費者,action 沒有返回值。

1.4 Apply 類方法

Apply 類方法指 thenApply、applyToEither 等。Apply 類方法的動作參數(shù)都是Function<? super T,? extends U> fn。例如 thenApply(Function<? super T,? extends U> fn)。如方法名和參數(shù)所示,action 將任務結(jié)果應用函數(shù)參數(shù) fn 做轉(zhuǎn)換,返回轉(zhuǎn)換后的結(jié)果,類似于 stream 中的 map。

2 單個任務執(zhí)行完成后執(zhí)行一個動作(action)

方法說明
public CompletableFuture<Void> thenRun(Runnable action)
thenRunAsync(Runnable action)
thenRunAsync(Runnable action, Executor executor)
任務完成后執(zhí)行 action,action 中不關心任務的結(jié)果,action 也沒有返回值
public CompletableFuture<Void> thenAccept(Consumer<? super T> action)
thenAcceptAsync(Consumer<? super T> action)
thenAcceptAsync(Consumer<? super T> action)
任務完成后執(zhí)行 action。如方法名和參數(shù)所示,action 是接受并消費任務結(jié)果的消費者,action 沒有返回值
public <U> CompletableFuture<U> thenApply(Function<? super T,? extends U> fn)
thenApplyAsync(Function<? super T,? extends U> fn)
thenApplyAsync(Function<? super T,? extends U> fn, Executor executor)
任務完成后執(zhí)行 action。action 將任務結(jié)果應用 action 的函數(shù)參數(shù)做轉(zhuǎn)換,返回轉(zhuǎn)換后的結(jié)果,類似于 stream 中的 map
public CompletableFuture<T> whenComplete(BiConsumer<? super T, ? super Throwable> action)
whenCompleteAsync(BiConsumer<? super T, ? super Throwable> action)
whenCompleteAsync(BiConsumer<? super T, ? super Throwable> action, Executor executor)
任務完成后或者異常時運行action。action 是接受并消費任務結(jié)果的消費者,并且有返回值??梢哉J為是支持異常處理的 thenAccept 版本。
public <U> CompletableFuture<U> handle(BiFunction<? super T, Throwable, ? extends U> fn)
handleAsync(BiFunction<? super T, Throwable, ? extends U> fn)
handleAsync(BiFunction<? super T, Throwable, ? extends U> fn, Executor executor)
任務完成后或者異常時運行action。可以認為是支持異常處理的 thenApply 版本。
public CompletableFuture exceptionally(Function<Throwable, ? extends T> fn)如果任務或者 action 發(fā)生異常,則會觸發(fā)exceptionally的調(diào)用相當于 try...catch

2.0 示例 exceptionally

@Test
void testCompletableFutureExceptionally(){
    CompletableFuture<Integer> first = CompletableFuture
            .supplyAsync(() -> {
                if (true) {
                    throw new RuntimeException("exception in task");
                }
                return "hello world";
            })
            .thenApply(data -> {
                if (true) {
                    throw new RuntimeException("exception in action");
                }
                return 1;
            })
            .exceptionally(e -> {
                System.out.println("[" + Thread.currentThread().getName() + "] " + " print exception stack trace" );
                e.printStackTrace(); // 異常捕捉處理,前面兩個處理環(huán)節(jié)的日常都能捕獲
                return 0;
            });
}

3 兩個任務執(zhí)行編排

下面表格列出的每個方法都有對應兩個版本的 async 方法,一個有executor 參數(shù),一個沒有。為了表格盡量簡潔,表格中就不再列出async 方法了

方法說明
public <U> CompletableFuture<U> thenCompose(Function<? super T,? extends CompletionStage> fn)串行組合兩個 CompletableFuture 任務,后一個任務依賴前一個任務的結(jié)果,后一個任務可以返回與第一個任務不同類型的返回值。執(zhí)行后一個任務的線程與前面討論 action 執(zhí)行的線程類似。
public CompletableFuture<Void> runAfterBoth(CompletionStage<?> other, Runnable action)這里有兩個并行任務,一個是runAfterBoth 調(diào)用本身所屬的CompletableFuture 實例A,一個是參數(shù) other 引用的任務B。兩個并行任務都完成后執(zhí)行 action,action 中不關心任務的結(jié)果,action 也沒有返回值
public <U> CompletableFuture<Void> thenAcceptBoth(CompletionStage<? extends U> other, BiConsumer<? super T, ? super U> action)與runAfterBoth 類似,也有兩個并行任務 A 和 B。兩個并行任務都完成后執(zhí)行 action。如方法名和參數(shù)所示,action 是接受并消費兩個任務結(jié)果的消費者,action 沒有返回值
public <U,V> CompletableFuture<V> thenCombine(CompletionStage<? extends U> other, BiFunction<? super T,? super U,? extends V> fn)與runAfterBoth 類似,也有兩個并行任務 A 和 B。兩個并行任務都完成后執(zhí)行 action,action 依賴兩個任務的結(jié)果,并對結(jié)果做轉(zhuǎn)換,返回一個新值
public CompletableFuture<Void> runAfterEither(CompletionStage<?> other, Runnable action)與runAfterBoth 類似,也有兩個并行任務 A 和 B。兩個并行任務任意一個完成后執(zhí)行 action,action 中不關心任務的結(jié)果,action 也沒有返回值
public CompletableFuture<Void> acceptEither(CompletionStage<? extends T> other, Consumer<? super T> action)與runAfterBoth 類似,也有兩個并行任務 A 和 B。兩個并行任務任意一個完成后執(zhí)行 action。如方法名和參數(shù)所示,action 是接受并消費兩個任務結(jié)果的消費者,action 沒有返回值
public <U> CompletableFuture<U> applyToEither(CompletionStage<? extends T> other, Function<? super T, U> fn)與runAfterBoth 類似,也有兩個并行任務 A 和 B。兩個并行任務任意一個完成后執(zhí)行 action。action 將任務結(jié)果應用 action 的函數(shù)參數(shù)做轉(zhuǎn)換,返回轉(zhuǎn)換后的結(jié)果,類似于 stream 中的 map

4 多個任務執(zhí)行編排

下面表格列出的每個方法都有對應兩個版本的 async 方法,一個有executor 參數(shù),一個沒有。為了表格盡量簡潔,表格中就不再列出async 方法了

方法說明
public static CompletableFuture<Void> allOf(CompletableFuture<?>... cfs)所有參數(shù)引用的任務都完成后,才觸發(fā)執(zhí)行當前的 CompletableFuture 實例任務。
public static CompletableFuture<Object> anyOf(CompletableFuture<?>... cfs)參數(shù)引用的任務中任何一個完成后,就會觸發(fā)執(zhí)行當前的 CompletableFuture 實例任務。

5 CompletableFuture 其他方法

方法說明
public boolean cancel(boolean mayInterruptIfRunning)如果任務未完成,以 CancellationException 異常結(jié)束任務。
public boolean isCancelled()判斷任務是否取消。
public T join()阻塞等待 獲取返回值
public T get() throws InterruptedException, ExecutionException
public T get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException
阻塞等待(有超時重載版本)獲取返回值。get 與 join區(qū)別,get 會拋出 checked 異常,調(diào)用代碼需要處理異常。join 沒有超時重載版本。
public T getNow(T valueIfAbsent)獲取返回值,如果任務未完成則返回valueIfAbsent 參數(shù)指定value
public boolean isDone()任務是否執(zhí)行完成

到此這篇關于Java中CompletableFuture 的詳細介紹的文章就介紹到這了,更多相關CompletableFuture 內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Java實現(xiàn)的Base64加密算法示例

    Java實現(xiàn)的Base64加密算法示例

    這篇文章主要介紹了Java實現(xiàn)的Base64加密算法,結(jié)合實例形式分析了Java實現(xiàn)的base64編碼轉(zhuǎn)換相關使用方法及操作注意事項,需要的朋友可以參考下
    2018-04-04
  • Java Scanner 類的使用小結(jié)

    Java Scanner 類的使用小結(jié)

    在筆試編程過程中,關于數(shù)據(jù)的讀取如果迷迷糊糊,那后來的編程即使想法很對,實現(xiàn)很好,也是徒勞,于是在這里認真總結(jié)了Java Scanner 類的使用,需要的朋友可以參考下
    2018-10-10
  • Java如何實現(xiàn)讀取txt文件內(nèi)容并生成Word文檔

    Java如何實現(xiàn)讀取txt文件內(nèi)容并生成Word文檔

    本文主要介紹了通過Java實現(xiàn)讀取txt文件中的內(nèi)容,并將內(nèi)容生成Word文檔。文章的代碼非常詳細,具有一定的學習價值,感興趣的小伙伴可以了解一下
    2021-12-12
  • sa-token?路由攔截式鑒權使用示例詳解

    sa-token?路由攔截式鑒權使用示例詳解

    這篇文章主要為大家介紹了sa-token?路由攔截式鑒權使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-07-07
  • 淺談Spring IoC容器的依賴注入原理

    淺談Spring IoC容器的依賴注入原理

    這篇文章主要介紹了淺談Spring IoC容器的依賴注入原理,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-03-03
  • 深入學習Hibernate持久化對象的三個狀態(tài)

    深入學習Hibernate持久化對象的三個狀態(tài)

    Hibernate中的對象有3中狀態(tài),瞬時對象(TransientObjects)、持久化對象(PersistentObjects)和離線對象(DetachedObjects也叫做脫管對象),下面通過本文給大家分享Hibernate持久化對象的三個狀態(tài),一起看看吧
    2017-09-09
  • 劍指Offer之Java算法習題精講求和篇

    劍指Offer之Java算法習題精講求和篇

    跟著思路走,之后從簡單題入手,反復去看,做過之后可能會忘記,之后再做一次,記不住就反復做,反復尋求思路和規(guī)律,慢慢積累就會發(fā)現(xiàn)質(zhì)的變化
    2022-03-03
  • 聊聊java多線程創(chuàng)建方式及線程安全問題

    聊聊java多線程創(chuàng)建方式及線程安全問題

    線程被稱為輕量級進程,是程序執(zhí)行的最小單位,它是指在程序執(zhí)行過程中,能夠執(zhí)行代碼的一個執(zhí)行單位。接下來通過本文給大家介紹java多線程創(chuàng)建方式及線程安全問題,感興趣的朋友一起看看吧
    2022-01-01
  • IDEA JarEditor編輯jar包方式(直接新增,修改,刪除jar包內(nèi)的class文件)

    IDEA JarEditor編輯jar包方式(直接新增,修改,刪除jar包內(nèi)的class文件)

    文章主要介紹了如何使用IDEA的JarEditor插件直接修改jar包內(nèi)的class文件,而不需要手動解壓、反編譯和重新打包,通過該插件,可以更方便地進行jar包的修改和測試
    2025-01-01
  • Java如何利用Socket進行數(shù)據(jù)讀寫

    Java如何利用Socket進行數(shù)據(jù)讀寫

    這篇文章主要介紹了Java如何利用Socket進行數(shù)據(jù)讀寫,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-10-10

最新評論

辽宁省| 咸阳市| 普兰县| 兴义市| 霞浦县| 泰来县| 汝阳县| 江源县| 嘉兴市| 黑龙江省| 荥经县| 南丹县| 德保县| 营口市| 灵台县| 宁远县| 灵丘县| 城口县| 肥城市| 青铜峡市| 林芝县| 仙居县| 道孚县| 和顺县| 绥宁县| 黔西| 浦城县| 永平县| 和林格尔县| 桦南县| 陆河县| 乌恰县| 柳河县| 郸城县| 丁青县| 巴林右旗| 衡南县| 桐梓县| 东兴市| 城口县| 西畴县|