一、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