深入了解JavaPromise:從多方面闡述

一、Promise的概念

Promise就是一種對異步操作結果的規範,類似於“保證書”,保證異步操作在未來一定會有一個返回值或異常拋出。

常見的Promise的狀態有三種:Pending(進行中)、Resolved(已成功完成)、Rejected(已失敗)。

public interface Promise extends Future {
    <U> Promise thenApply(Function<? super V, ? extends U> fn);
    <U> Promise<U> thenCompose(Function<? super V, ? extends CompletionStage<? extends U>> fn);
    Promise<V> exceptionally(Function<Throwable, ? extends V> fn);
    Promise<V> whenComplete(BiConsumer<? super V, ? super Throwable> action);
    Promise<V> whenCompleteAsync(BiConsumer<? super V, ? super Throwable> action);
}

JavaPromise就是在java.util.concurrent.Future的基礎上分析封裝出來的Promise實現。

下面我們就從不同的角度來深入了解JavaPromise的相關知識。

二、使用JavaPromise實現異步任務

在多線程編程中,異步任務非常常見,可以通過JavaPromise輕鬆實現異步任務操作。

例如下面的代碼:我們創建一個簡單的異步任務,該任務在1秒鐘後會返回一個結果。

Promise<String> promise = CompletableFuture.supplyAsync(() -> {
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            throw new IllegalStateException(e);
        }
        return "異步任務已完成";
});

注意:以上代碼中的supplyAsync方法創建了異步任務供後續調用使用。

三、JavaPromise中的thenApply方法

JavaPromise的thenApply方法可以將一個Promise實例轉換成另一個Promise實例,並可以在轉換的同時對得到的結果進行一些處理。

例如下面的代碼:我們創建一個簡單的異步任務,該任務在1秒鐘後會返回一個結果。利用thenApply方法我們可以對結果進行處理。

Promise<String> promise = CompletableFuture.supplyAsync(() -> {
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                throw new IllegalStateException(e);
            }
            return "a";
        })
        .thenApply(s -> s + "b")
        .thenApply(s -> s + "c");

通過thenApply方法,我們可以將獲取的結果轉為另一個Promise,並對其進行處理。

四、JavaPromise中的thenCompose方法

thenCompose方法也是將一個Promise實例轉換成另一個Promise實例,不同的是轉換後的Promise是一個嵌套的Promise,可以一步步的對多個Promise進行處理。

例如下面的代碼:我們創建了兩個簡單的異步任務,第二個任務需要第一個任務的結果作為輸入。因此我們需要以thenCompose的形式,嵌套執行兩個異步任務。

Promise<String> promise = CompletableFuture.supplyAsync(() -> {
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                throw new IllegalStateException(e);
            }
            return "a";
        })
        .thenCompose(s -> CompletableFuture.supplyAsync(() -> {
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                throw new IllegalStateException(e);
            }
            return s + "b";
        }));

注意:以上代碼中第二個異步任務需要調用第一個任務的結果作為輸入。

五、JavaPromise中的exceptionally方法

exceptionally方法用於在異步任務執行過程中現有異常,或任務失敗時,提供一個備用值或者執行回調函數。

例如下面的代碼:我們創建了一個簡單的異步任務,該任務會隨機拋出異常。為了避免程序拋出異常後無法繼續執行下去,我們使用exceptionally方法對異常進行處理,並在處理時提供一個備用值。

Promise<String> promise = CompletableFuture.supplyAsync(() -> {
            Random random = new Random();
            if (random.nextBoolean()) {
                throw new RuntimeException("隨機異常");
            }
            return "正常執行完成";
        })
        .exceptionally(ex -> "備用值");

在以上代碼中,發生異常時,exceptionally方法會提供一個備用值。

六、JavaPromise中的whenComplete方法

whenComplete方法與exceptionally方法類似,也是當異步任務執行過程中發生異常時提供一個備用值或者執行回調函數的方法。

不同的是,whenComplete方法無論任務是否執行成功或失敗都會得到執行。而且還可以在執行回調函數時繼續對Future的操作。

例如下面的代碼:我們創建一個簡單的異步任務,當任務在1秒鐘後完成時,根據隨機值拋出異常。在異常發生時,我們將對異常進行處理,並繼續異步操作。

Promise<String> promise = CompletableFuture.supplyAsync(() -> {
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                throw new IllegalStateException(e);
            }
            Random random = new Random();
            if (random.nextBoolean()) {
                throw new RuntimeException("隨機異常");
            }
            return "正常執行完成";
        })
        .whenComplete((s, ex) -> {
            if (ex != null) {
                System.out.println("發生了異常:" + ex.getMessage());
            }
            System.out.println("異步任務已完成:" + s);
        });

七、JavaPromise中的whenCompleteAsync方法

whenCompleteAsync方法與whenComplete方法類似,也是當異步任務執行過程中發生異常時提供一個備用值或者執行回調函數的方法。

不同的是,whenCompleteAsync方法提供了異步執行回調函數的方式。

例如下面的代碼:我們創建一個簡單的異步任務,在1秒鐘後隨機拋出異常。在異常發生時,我們將對異常進行處理,並在回調處理中進行日誌記錄。並且在處理日誌時,我們使用了whenCompleteAsync方法進行異步日誌記錄操作。

Executors.newSingleThreadExecutor().submit(() -> {
            Promise<String> promise = CompletableFuture.supplyAsync(() -> {
                        try {
                            TimeUnit.SECONDS.sleep(1);
                        } catch (InterruptedException e) {
                            throw new IllegalStateException(e);
                        }
                        Random random = new Random();
                        if (random.nextBoolean()) {
                            throw new RuntimeException("隨機異常");
                        }
                        return "正常執行完成";
                    });
            promise.whenCompleteAsync((s, ex) -> {
                if (ex != null) {
                    System.out.println("發生了異常:" + ex.getMessage());
                }
                Executors.newSingleThreadExecutor().submit(() -> {
                    System.out.println("日誌輸出:" + System.currentTimeMillis());
                });
            });
        });

在該代碼中,我們將日誌記錄異步操作通過whenCompleteAsync方法進行了處理。

以上就是對JavaPromise的介紹,通過以上幾點我們可以看出,JavaPromise是Java8中新增的異步編程技術,它可以輕鬆實現異步操作,並提供了靈活的異步操作方式與回調處理機制。

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/286706.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-12-23 03:48
下一篇 2024-12-23 03:48

相關推薦

  • Python取較大值的多方面

    Python是一款流行的編程語言,廣泛應用於數據分析、科學計算、Web開發等領域。作為一名全能開發工程師,了解Python的取較大值方法非常必要。本文將從多個方面對Python取較…

    編程 2025-04-27
  • 深入解析Vue3 defineExpose

    Vue 3在開發過程中引入了新的API `defineExpose`。在以前的版本中,我們經常使用 `$attrs` 和` $listeners` 實現父組件與子組件之間的通信,但…

    編程 2025-04-25
  • 深入理解byte轉int

    一、字節與比特 在討論byte轉int之前,我們需要了解字節和比特的概念。字節是計算機存儲單位的一種,通常表示8個比特(bit),即1字節=8比特。比特是計算機中最小的數據單位,是…

    編程 2025-04-25
  • 深入理解Flutter StreamBuilder

    一、什麼是Flutter StreamBuilder? Flutter StreamBuilder是Flutter框架中的一個內置小部件,它可以監測數據流(Stream)中數據的變…

    編程 2025-04-25
  • 深入探討OpenCV版本

    OpenCV是一個用於計算機視覺應用程序的開源庫。它是由英特爾公司創建的,現已由Willow Garage管理。OpenCV旨在提供一個易於使用的計算機視覺和機器學習基礎架構,以實…

    編程 2025-04-25
  • 深入了解scala-maven-plugin

    一、簡介 Scala-maven-plugin 是一個創造和管理 Scala 項目的maven插件,它可以自動生成基本項目結構、依賴配置、Scala文件等。使用它可以使我們專註於代…

    編程 2025-04-25
  • 深入了解LaTeX的腳註(latexfootnote)

    一、基本介紹 LaTeX作為一種排版軟件,具有各種各樣的功能,其中腳註(footnote)是一個十分重要的功能之一。在LaTeX中,腳註是用命令latexfootnote來實現的。…

    編程 2025-04-25
  • 深入剖析MapStruct未生成實現類問題

    一、MapStruct簡介 MapStruct是一個Java bean映射器,它通過註解和代碼生成來在Java bean之間轉換成本類代碼,實現類型安全,簡單而不失靈活。 作為一個…

    編程 2025-04-25
  • 深入了解Python包

    一、包的概念 Python中一個程序就是一個模塊,而一個模塊可以引入另一個模塊,這樣就形成了包。包就是有多個模塊組成的一個大模塊,也可以看做是一個文件夾。包可以有效地組織代碼和數據…

    編程 2025-04-25
  • 深入理解Python字符串r

    一、r字符串的基本概念 r字符串(raw字符串)是指在Python中,以字母r為前綴的字符串。r字符串中的反斜杠(\)不會被轉義,而是被當作普通字符處理,這使得r字符串可以非常方便…

    編程 2025-04-25

發表回復

登錄後才能評論