日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

CompletableFuture详解~创建实例

發布時間:2024/7/23 编程问答 48 豆豆
生活随笔 收集整理的這篇文章主要介紹了 CompletableFuture详解~创建实例 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

創建 CompletableFuture 對象實例我們可以使用如下幾個方法:

static CompletableFuture<U> completedFuture(U value)//使用forkjoin公共線程池 static CompletableFuture<Void> runAsync(Runnable runnable) static CompletableFuture<U> supplyAsync(Supplier<U> supplier)//使用自定義線程池 static CompletableFuture<Void> runAsync(Runnable runnable, Executor executor) static CompletableFuture<U> supplyAsync(Supplier<U> supplier, Executor executor)

第一個方法創建一個具有默認結果的 CompletableFuture,這個沒啥好講。我們重點講述下下面四個異步方法。

前兩個方法 runAsync 不支持返回值,而 supplyAsync可以支持返回結果。

這個兩個方法默認將會使用公共的?ForkJoinPool?線程池執行,這個線程池默認線程數是?CPU?的核數。

可以設置 JVM option:-Djava.util.concurrent.ForkJoinPool.common.parallelism 來設置 ForkJoinPool 線程池的線程數

使用共享線程池將會有個弊端,一旦有任務被阻塞,將會造成其他任務沒機會執行。所以強烈建議使用后兩個方法,根據任務類型不同,主動創建線程池,進行資源隔離,避免互相干擾。

-------------------------------------------------------

CompletableFuture的創建:

  • 說明:

    • 兩個重載方法之間的區別 => 后者可以傳入自定義Executor,前者是默認的,使用的ForkJoinPool

    • supplyAsync和runAsync方法之間的區別 => 前者有返回值,后者無返回值

    • Supplier是函數式接口,因此該方法需要傳入該接口的實現類,追蹤源碼會發現在run方法中會調用該接口的方法。因此使用該方法創建CompletableFuture對象只需重寫Supplier中的get方法,在get方法中定義任務即可。又因為函數式接口可以使用Lambda表達式,和new創建CompletableFuture對象相比代碼會簡潔不少

    • 使用new方法

CompletableFuture<Double> futurePrice = new CompletableFuture<>();

使用CompletableFuture#completedFuture靜態方法創建

public static <U> CompletableFuture<U> completedFuture(U value) {return new CompletableFuture<U>((value == null) ? NIL : value); }
  • 參數的值為任務執行完的結果,一般該方法在實際應用中較少應用

  • 使用 CompletableFuture#supplyAsync靜態方法創建 supplyAsync有兩個重載方法:

//方法一 public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier) {return asyncSupplyStage(asyncPool, supplier); } //方法二 public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier,Executor executor) {return asyncSupplyStage(screenExecutor(executor), supplier); }
  • 使用CompletableFuture#runAsync靜態方法創建 runAsync有兩個重載方法

//方法一 public static CompletableFuture<Void> runAsync(Runnable runnable) {return asyncRunStage(asyncPool, runnable); } //方法二 public static CompletableFuture<Void> runAsync(Runnable runnable, Executor executor) {return asyncRunStage(screenExecutor(executor), runnable); }

結果的獲取:?對于結果的獲取CompltableFuture類提供了四種方式

//方式一 public T get() //方式二 public T get(long timeout, TimeUnit unit) //方式三 public T getNow(T valueIfAbsent) //方式四 public T join()
  • 說明:

    示例:

    • get()和get(long timeout, TimeUnit unit) => 在Future中就已經提供了,后者提供超時處理,如果在指定時間內未獲取結果將拋出超時異常

    • getNow => 立即獲取結果不阻塞,結果計算已完成將返回結果或計算過程中的異常,如果未計算完成將返回設定的valueIfAbsent值

    • join => 方法里不會拋出異常

public class AcquireResultTest {public static void main(String[] args) throws ExecutionException, InterruptedException {//getNow方法測試CompletableFuture<String> cp1 = CompletableFuture.supplyAsync(() -> {try {Thread.sleep(60 * 1000 * 60 );} catch (InterruptedException e) {e.printStackTrace();}return "hello world";});System.out.println(cp1.getNow("hello h2t"));//join方法測試CompletableFuture<Integer> cp2 = CompletableFuture.supplyAsync((()-> 1 / 0));System.out.println(cp2.join());//get方法測試CompletableFuture<Integer> cp3 = CompletableFuture.supplyAsync((()-> 1 / 0));System.out.println(cp3.get());} }

說明:

  • 第一個執行結果為hello h2t,因為要先睡上1分鐘結果不能立即獲取

  • join方法獲取結果方法里不會拋異常,但是執行結果會拋異常,拋出的異常為CompletionException

  • get方法獲取結果方法里將拋出異常,執行結果拋出的異常為ExecutionException

  • 異常處理:?使用靜態方法創建的CompletableFuture對象無需顯示處理異常,使用new創建的對象需要調用completeExceptionally方法設置捕獲到的異常,舉例說明:

CompletableFuture completableFuture = new CompletableFuture(); new Thread(() -> {try {//doSomething,調用complete方法將其他方法的執行結果記錄在completableFuture對象中completableFuture.complete(null);} catch (Exception e) {//異常處理completableFuture.completeExceptionally(e);} }).start();

總結

以上是生活随笔為你收集整理的CompletableFuture详解~创建实例的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。