Java8 CompletableFuture 異步執(zhí)行操作
1.簡介
CompletableFuture 是 JDK8 提供的一個異步執(zhí)行工具。
示例1:
public static void main(String[] args) throws ExecutionException, InterruptedException { CompletableFuture<Void> future = CompletableFuture.runAsync(() -> { for (int i = 0; i < 3; i++) { System.out.println(i); try { Thread.sleep(1000L); } catch (InterruptedException ignored) { } } System.out.println("Future Finished."); }); System.out.println("Main Thread Finished."); future.get(); }
輸出結(jié)果1:
2.異步執(zhí)行
CompletableFuture 提供了兩個方法用于異步執(zhí)行:
CompletableFuture.runAsync,沒有返回值
;
CompletableFuture.supplyAsync,有返回值
。
示例:
public static void main(String[] args) throws ExecutionException, InterruptedException { // runAsync 沒有返回值 CompletableFuture<Void> future1 = CompletableFuture.runAsync(() -> System.out.println("future1 executed.")); // supplyAsync 有返回值 CompletableFuture<Object> future2 = CompletableFuture.supplyAsync(() -> { System.out.println("future2 executed."); return "result"; }); System.out.println("future1.get(): " + future1.get()); System.out.println("future2.get(): " + future2.get()); }
輸出結(jié)果:
3.守護(hù)線程
CompletableFuture返回的Future默認(rèn)為守護(hù)線程
,如果不調(diào)用get()獲取結(jié)果,主線程結(jié)束后會自動結(jié)束
。主要有以下4種情景:
- 情景1: 執(zhí)行時間 > 主線程時間,異步線程
會執(zhí)行
; - 情景2: 執(zhí)行時間 > 主線程,是守護(hù)線程,會被殺死,異步線程
不會執(zhí)行
; - 情景3: 執(zhí)行時間 > 主線程,但是不是守護(hù)線程,不會被殺死,異步線程
會執(zhí)行
; - 情景4: ExecutorService.submit(),默認(rèn)不是守護(hù)線程,不會被殺死,異步線程
會執(zhí)行
。
示例:
public static void main(String[] args) { ExecutorService executorService = Executors.newFixedThreadPool(2); // 1.執(zhí)行時間 < 主線程,會打印 CompletableFuture<Void> future1 = CompletableFuture.runAsync(() -> System.out.println("Thread1 是否為守護(hù)線程 : " + Thread.currentThread().isDaemon())); // 2.執(zhí)行時間 > 主線程,是守護(hù)線程,會被殺死,不會打印 CompletableFuture.runAsync(() -> { try { Thread.sleep(3000L); System.out.println("Thread2 是否為守護(hù)線程 : " + Thread.currentThread().isDaemon()); } catch (InterruptedException e) { e.printStackTrace(); }}); // 3.執(zhí)行時間 > 主線程,但是不是守護(hù)線程,不會被殺死,會打印 CompletableFuture.runAsync(() -> { try { Thread.sleep(1000L); System.out.println("Thread3 等待1秒"); System.out.println("Thread3 是否為守護(hù)線程 : " + Thread.currentThread().isDaemon()); } catch (InterruptedException e) { e.printStackTrace(); }}, executorService); // 4.ExecutorService.submit(),默認(rèn)不是守護(hù)線程,不會被殺死,會打印。 executorService.submit(() -> { try { Thread.sleep(2000L); System.out.println("Thread4 等待2秒"); System.out.println("Thread4 是否為守護(hù)線程 : " + Thread.currentThread().isDaemon()); } catch (InterruptedException e) { e.printStackTrace(); }}); // 主線程執(zhí)行完畢 System.out.println("Main Thread Finished."); executorService.shutdown(); }
輸出結(jié)果2:
4.處理執(zhí)行結(jié)果
CompletableFuture還封裝了很多處理執(zhí)行結(jié)果
操作。操作太多,列舉比較常用的幾種:
thenAccept(): 對結(jié)果進(jìn)行使用;
thenApply(): 對結(jié)果進(jìn)行轉(zhuǎn)換;
exceptionally(): 對異常進(jìn)行處理;
whenComplete(): 相當(dāng)于 thenAccept() + thenApply() + exceptionally().
示例:
public static void main(String[] args) { // thenAccept對結(jié)果進(jìn)行使用 System.out.println("------------------------------"); CompletableFuture.supplyAsync(() -> "Thread1 Finished.").thenAccept(System.out::println); // thenApply對結(jié)果進(jìn)行轉(zhuǎn)換 System.out.println("------------------------------"); CompletableFuture.supplyAsync(() -> "Thread2 Finished.") .thenApply(s -> s + " + thenApply()") .thenAccept(System.out::println); // exceptionally對異常進(jìn)行處理 System.out.println("------------------------------"); CompletableFuture.supplyAsync(() -> {throw new RuntimeException("Thread3 Failed.");}) .exceptionally(Throwable::toString).thenAccept(System.out::println); // 主線程執(zhí)行完畢 System.out.println("------------------------------"); System.out.println("Main Thread Finished."); }
輸出結(jié)果:
whenComplete() 示例:
public static void main(String[] args) throws ExecutionException, InterruptedException { // thenAccept對結(jié)果進(jìn)行使用 System.out.println("------------------------------"); CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "Thread1 Finished.").whenComplete(new BiConsumer<String, Throwable>() { @Override public void accept(String s, Throwable throwable) { System.out.println("result: " + s); System.out.println("throwable: " + throwable); } }); // exceptionally對異常進(jìn)行處理 System.out.println("------------------------------"); CompletableFuture.supplyAsync(() -> { throw new RuntimeException("Thread3 Failed."); }).whenComplete(new BiConsumer<Object, Throwable>() { @Override public void accept(Object s, Throwable throwable) { System.out.println("result: " + s); System.out.println("throwable: " + throwable); } }); System.out.println("------------------------------"); System.out.println("future.get(): " + future.get()); // 主線程執(zhí)行完畢 System.out.println("------------------------------"); System.out.println("Main Thread Finished."); }
輸出結(jié)果:
整理完畢,完結(jié)撒花~
以上就是Java8 CompletableFuture 異步執(zhí)行的詳細(xì)內(nèi)容,更多關(guān)于Java8 CompletableFuture 異步執(zhí)行的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Java實現(xiàn)的不同圖片居中剪裁生成同一尺寸縮略圖功能示例
這篇文章主要介紹了Java實現(xiàn)的不同圖片居中剪裁生成同一尺寸縮略圖功能,涉及java針對圖片的讀取、屬性修改等相關(guān)操作技巧,需要的朋友可以參考下2017-09-09Java實現(xiàn)在Word中嵌入多媒體(視頻、音頻)文件
這篇文章主要介紹了Java如何實現(xiàn)在Word中嵌入多媒體(視頻、音頻)文件,文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)java有一定的幫助,感興趣的同學(xué)可以了解一下2021-12-12java讀取配置文件自定義字段(yml、properties)
本文主要介紹了java讀取配置文件自定義字段(yml、properties),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-07-07Java 處理超大數(shù)類型之BigInteger案例詳解
這篇文章主要介紹了Java 處理超大數(shù)類型之BigInteger案例詳解,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-09-09Java子類實例化總是默認(rèn)調(diào)用父類的無參構(gòu)造操作
這篇文章主要介紹了Java子類實例化總是默認(rèn)調(diào)用父類的無參構(gòu)造操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-10-10