Java異步方法CompletableFuture類的使用

Java中常用的異步方法

1、使用線程:你可以創建一個新的線程來執行異步操作。這可以通過直接創建Thread對象并啟動它,或者使用線程池來管理線程的生命周期。

new Thread(() -> {// 異步操作代碼
}).start();

2、使用線程池Executor框架:Executor框架提供了一種更高級別的異步執行機制,可以管理線程池和任務調度。

ExecutorService executor = Executors.newFixedThreadPool(10);
executor.submit(() -> {// 異步操作代碼
});
executor.shutdown();

3、使用Java 8引入的CompletableFuture類:CompletableFuture類提供了一種更便捷的方式來執行異步操作,并處理操作完成后的結果。

CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {// 異步操作代碼
});// 可以在異步操作完成后執行回調函數
future.thenRun(() -> {// 操作完成后的處理代碼
});

4、使用第三方庫:除了Java內置的工具,還有許多第三方庫可用于實現異步操作,例如Guava的ListenableFuture等。

CompletableFuture類使用

CompletableFuture 類是 Java 中用于處理異步編程的強大工具。下面是 CompletableFuture 類的一些常用方法的詳細解釋:?

1. ?supplyAsync(Supplier<U> supplier) :創建一個 CompletableFuture,該 CompletableFuture 會異步執行 Supplier 方法,并返回計算結果。 ?

CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {// 異步操作:計算兩個整數的和int a = 5;int b = 10;return a + b;
});
// get() 方法,該方法是阻塞的,直到異步操作完成或超時。
Integer val = future.get();
System.out.println("獲取異步加載的值:" + val);

2. ?thenApply(Function<? super T,? extends U> fn) :在 CompletableFuture 完成后應用給定的函數 fn,將 CompletableFuture 的結果轉換為另一種類型,并返回一個新的 CompletableFuture。 ?

CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {// 異步操作:獲取用戶年齡return getUserAge();
}).thenApply(age -> {// 將年齡轉換為字符串return "返回用戶年齡信息: " + String.valueOf(age);
});

3. ?thenAccept(Consumer<? super T> action) :在 CompletableFuture 完成后執行給定的動作 action,對 CompletableFuture 的結果進行消費,但不返回新的 CompletableFuture。 ?

CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {// 異步操作:獲取用戶年齡return getUserAge();
}).thenAccept(age -> {// 沒有返回值System.out.println("thenAccept沒有返回值: " + String.valueOf(age));
});

4. ?thenRun(Runnable action) :在 CompletableFuture 完成后執行給定的動作 action,對 CompletableFuture 的結果不進行消費,也不返回新的 CompletableFuture。 ?

CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {// 返回值return "Result";
});CompletableFuture<Void> thenRunFuture = future.thenRun(() -> {// 使用 thenRun() 執行一個操作,在計算完成后打印一條消息System.out.println("執行完成!");
});// 獲取值
thenRunFuture.get();

5. ?thenCompose(Function<? super T,? extends CompletionStage<U>> fn) :在 CompletableFuture 完成后應用給定的函數 fn,將 CompletableFuture 的結果傳遞給該函數,并返回一個新的 CompletableFuture。簡單的說就是用于將兩個 CompletableFuture 對象串聯起來執行。

// 使用場景:
// 假設有兩個異步任務,任務 A 返回一個結果,任務 B 根據任務 A 的結果進行計算并返回最終結果。
CompletableFuture<Integer> futureA = CompletableFuture.supplyAsync(() -> {// 異步任務 Areturn 2;
});CompletableFuture<Integer> futureB = futureA.thenCompose(resultA -> {// 異步任務 B,根據任務 A 的結果進行計算int resultB = resultA * 3;return CompletableFuture.completedFuture(resultB);
});// 最終結果輸出6
futureB.thenAccept(finalResult -> System.out.println("最終結果:" + finalResult));

6. ?exceptionally(Function<Throwable,? extends T> fn) :在 CompletableFuture 發生異常時應用給定的函數 fn,返回一個新的 CompletableFuture,該 CompletableFuture 的結果是由異常處理函數提供的,用于處理異步任務中的異常情況.

// 使用場景:
// 假設有一個異步任務,計算兩個數的商,出現除零異常。在發生異常時返回一個默認值
CompletableFuture<Double> future = CompletableFuture.supplyAsync(() -> {int dividend = 10;int divisor = 0;return dividend / divisor;
});CompletableFuture<Double> resultFuture = future.exceptionally(ex -> {System.out.println("發生異常:" + ex);return 0.0; // 返回默認值
});// 輸出:
// 發生異常:java.lang.ArithmeticException: / by zero
// 計算結果:0.0
resultFuture.thenAccept(result -> System.out.println("計算結果:" + result));

7. ?handle(BiFunction<? super T,Throwable,? extends U> fn) :在 CompletableFuture 完成后應用給定的函數 fn,無論 CompletableFuture 是否發生異常,該函數都會被調用,并返回一個新的 CompletableFuture,用于處理異步任務的結果(包括正常結果和異常情況)。

CompletableFuture<Double> future = CompletableFuture.supplyAsync(() -> {int dividend = 10;int divisor = 2;return dividend / divisor;
});CompletableFuture<String> resultFuture = future.handle((result, ex) -> {if (ex != null) {System.out.println("發生異常:" + ex);return "默認值"; // 返回默認值} else {return "計算結果:" + result;}
});// 輸出:
// 計算結果:5.0
resultFuture.thenAccept(result -> System.out.println(result));

8. ?allOf(CompletableFuture<?>... cfs) :等待多個 CompletableFuture 完成,并返回一個新的 CompletableFuture,該新的 CompletableFuture 在所有輸入的 CompletableFuture 都完成后才會完成。?

注意:allOf() 方法返回的是 CompletableFuture<Void> ,因為它只關注所有CompletableFuture的完成狀態,而不關心具體的結果。如果你需要獲取每個CompletableFuture的結果,你可以在 allOf() 之后使用 get() 方法來獲取每個CompletableFuture的結果。

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;public class CompletableFutureExample {public static void main(String[] args) {CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> {try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}return "Result from Future 1";});CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> {try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}return "Result from Future 2";});CompletableFuture<String> future3 = CompletableFuture.supplyAsync(() -> {try {Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}return "Result from Future 3";});CompletableFuture<Void> allFutures = CompletableFuture.allOf(future1, future2, future3);try {allFutures.get();System.out.println("所有任務都完成了,開始獲取值:");System.out.println("獲取 Future 1 的值: " + future1.get());System.out.println("獲取 Future 2 的值: " + future2.get());System.out.println("獲取 Future 3 的值: " + future3.get());} catch (InterruptedException | ExecutionException e) {e.printStackTrace();}}
}

9. ?anyOf(CompletableFuture<?>... cfs) :等待多個 CompletableFuture 中的任意一個完成,并返回一個新的 CompletableFuture,該新的 CompletableFuture 在其中任意一個 CompletableFuture 完成時就會完成。?

CompletableFuture.anyOf() 方法常用于以下場景:當你想并發執行多個異步任務,并且只需要獲取第一個完成的任務的結果時,它非常有用。在有多個獨立任務且只關心第一個成功完成的任務結果時,它可以發揮作用。

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;public class CompletableFutureExample {public static void main(String[] args) {CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> {try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}return "Result from Future 1";});CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> {try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}return "Result from Future 2";});CompletableFuture<String> future3 = CompletableFuture.supplyAsync(() -> {try {Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}return "Result from Future 3";});CompletableFuture<Object> anyFuture = CompletableFuture.anyOf(future1, future2, future3);try {System.out.println("打印任務的完成狀態: " + anyFuture.isDone());Object result = anyFuture.get();System.out.println("有一個任務完成了,就不管別的任務了: " + result);} catch (InterruptedException | ExecutionException e) {e.printStackTrace();}}
}

Future 和 AsyncResult的區別和使用場景

1. Future 接口:?
? ?- Future 接口是 Java 提供的一個異步操作的結果的占位符。它表示一個可能完成或者失敗的異步操作。?
? ?- Future 接口提供了一些方法(如 ?get() 、 isDone() 、 cancel() ?等)來獲取異步操作的結果、檢查操作是否完成以及取消操作。?
? ?- Future 接口的一個主要限制是它只能通過輪詢來判斷異步操作是否完成,這樣可能會導致線程阻塞。?

// get()獲取值
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "Hello, World!");
String result = future.get();
System.out.println("阻塞直到獲取值" + result);// isDone()是否完成
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "Hello, World!");
boolean done = future.isDone();
System.out.println("任務是否完成:" + done);// cancel()取消異步任務的執行
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {// 模擬一個長時間運行的任務try {Thread.sleep(5000);} catch (InterruptedException e) {e.printStackTrace();}return "Hello, World!";
});
boolean canceled = future.cancel(true);
System.out.println("任務是否被取消:" + canceled);

2. AsyncResult 接口:?
? ?- AsyncResult 接口是 Vert.x 框架中的一個特定實現,用于表示異步操作的結果。?
? ?- AsyncResult 接口繼承自 Future 接口,并提供了更多的方法和功能,使得處理異步操作更加方便。?
? ?- AsyncResult 接口提供了一種更靈活的方式來處理異步操作的結果,包括處理成功和失敗的情況,并可以獲取操作的異常信息。?

// 此處使用了異步注解、結合AsyncResult使用的舉例
@Async(THREAD_NAME)
public Future<Integer> ruleTotal() {return new AsyncResult<Integer>(testMapper.obtainCount());
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/39208.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/39208.shtml
英文地址,請注明出處:http://en.pswp.cn/news/39208.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Spring Boot 支持多種環境,包括開發環境、測試環境、預發布環境和生產環境。

Spring Boot 支持多種環境&#xff0c;包括開發環境、測試環境、預發布環境和生產環境。不同的環境具有不同的配置&#xff0c;可以在不同的環境中對應用程序進行測試、驗證和部署。以下是每種環境的用途和相應的代碼案例。 開發環境 開發環境是開發人員在本地進行開發的環境&…

AI Chat 設計模式:15. 橋接模式

本文是該系列的第十五篇&#xff0c;采用問答式的方式展開&#xff0c;問題由我提出&#xff0c;答案由 Chat AI 作出&#xff0c;灰色背景的文字則主要是我的一些思考和補充。 問題列表 Q.1 如果你是第一次接觸橋接模式&#xff0c;那么你會有哪些疑問呢&#xff1f;A.1Q.2 什…

內網隧道—HTTP\DNS\ICMP

本文僅限于安全研究和學習&#xff0c;用戶承擔因使用此工具而導致的所有法律和相關責任&#xff01; 作者不承擔任何法律和相關責任&#xff01; HTTP隧道 Neo-reGeorg Neo-reGeorg 是一個旨在積極重構 reGeorg 的項目&#xff0c;目的是&#xff1a; 提高可用性&#xff0…

山西電力市場日前價格預測【2023-08-17】

日前價格預測 預測明日&#xff08;2023-08-17&#xff09;山西電力市場全天平均日前電價為376.70元/MWh。其中&#xff0c;最高日前電價為431.75元/MWh&#xff0c;預計出現在19: 45。最低日前電價為339.25元/MWh&#xff0c;預計出現在13: 15。 價差方向預測 1&#xff1a; 實…

python實現抽獎小程序

使用Python的Tkinter庫來添加抽獎程序的界面操作。下面是一個示例代碼&#xff1a; import random import tkinter as tkdef lottery():prizes [一等獎, 二等獎, 三等獎, 謝謝參與]winner random.choice(prizes)result_label.config(text恭喜您獲得了{}&#xff01;.format(…

未出現過的最小正整數

給定一個長度為 n 的整數數組&#xff0c;請你找出未在數組中出現過的最小正整數。 樣例 輸入1&#xff1a;[-5, 3, 2, 3]輸出1&#xff1a;1輸入2&#xff1a;[1, 2, 3]輸出2&#xff1a;4數據范圍 1≤n≤105 , 數組中元素的取值范圍 [?109,109]。 代碼&#xff1a; c…

MySql主從復制1032錯誤(Slave_IO_Running: Yes Slave_SQL_Running: No)

MySql主從復制1032錯誤&#xff08;Slave_IO_Running: Yes Slave_SQL_Running: No&#xff09; Slave_IO_Running: Yes Slave_SQL_Running: No報錯&#xff1a; Last_SQL_Error: Could not execute Delete_rows event on table hr.test; Can’t find record in ‘test’, Erro…

【Unity造輪子】制作一個簡單的2d抓勾效果(類似蜘蛛俠的技能)

文章目錄 前言開始1. 實現簡單的抓勾效果2. 高階鉤爪效果 源碼參考完結 前言 歡迎閱讀本文&#xff0c;本文將向您介紹如何使用Unity游戲引擎來實現一個簡單而有趣的2D抓勾效果&#xff0c;類似于蜘蛛俠的獨特能力。抓勾效果是許多動作游戲和平臺游戲中的常見元素&#xff0c;…

【AI繪畫】3分鐘學會ikun幻術圖

目錄 前言一、效果展示二、準備工作三、操作步驟3.1平臺創建實例3.2 啟動SD 四、安裝QR Code Monster 模型五、成圖 前言 大家熱愛的ikun幻術在今天的分享中將呈現。在本文中&#xff0c;我們將揭示一個備受歡迎的圖像幻術技術&#xff0c;讓您感受到令人驚嘆的視覺創造力。 …

springboot+vue游戲攻略推薦網站的設計與開發_s5832

熱門網游推薦網站是一個利用JAVA技術建設的網上管理系統&#xff0c;在熱門網游推薦管理中實現信息化。系統的設計就是為了迎合廣大用戶需求而創建的一個界面簡潔、有定向內容、業務邏輯簡單易操作的熱門網游推薦網站。本文以熱門網游推薦為例&#xff0c;提出了利用JAVA技術設…

Angular中的ActivatedRoute和Router

Angular中的ActivatedRoute和Router解釋 在Angular中&#xff0c;ActivatedRoute和Router是兩個核心的路由服務。他們都提供可以用來檢查和操作當前頁面路由信息的方法和屬性。 ActivatedRoute ActivatedRoute是一個保存關于當前路由狀態&#xff08;如路由參數、查詢參數以…

Linux下grep通配容易混淆的地方

先上一張圖: 我希望找到某個版本為8的一個libXXX.8XXX.so ,那么應該怎么寫呢? 先看這種寫法對不對: 是不是結果出乎你的意料之外? 那么我們來看一下規則: 這里的 "*" 表示匹配前一個字符的零個或多個 于是我們就不難理解了: lib*8*.so 表示 包…

醫療PACS源碼,支持三維多平面重建、三維容積重建、三維表面重建、三維虛擬內窺鏡

C/S架構的PACS系統源碼&#xff0c;PACS主要進行病人信息和影像的獲取、處理、存儲、調閱、檢索、管理&#xff0c;并通過網絡向全院提供病人檢查影像及診斷報告&#xff1b;各影像科室之間共享不同設備的病人檢查影像及診斷報告;在診斷工作站上&#xff0c;調閱HIS中病人的其它…

拒絕擺爛!C語言練習打卡第二天

&#x1f525;博客主頁&#xff1a;小王又困了 &#x1f4da;系列專欄&#xff1a;每日一練 &#x1f31f;人之為學&#xff0c;不日近則日退 ??感謝大家點贊&#x1f44d;收藏?評論?? 目錄 一、選擇題 &#x1f4dd;1.第一題 &#x1f4dd;2.第二題 &#x1f4dd;…

P1304 哥德巴赫猜想

題目描述 輸入一個偶數 N N N&#xff0c;驗證 4 ~ N 4\sim N 4~N 所有偶數是否符合哥德巴赫猜想&#xff1a;任一大于 2 2 2 的偶數都可寫成兩個質數之和。如果一個數不止一種分法&#xff0c;則輸出第一個加數相比其他分法最小的方案。例如 10 10 10&#xff0c; 10 …

Springboot寫單元測試

導入依賴 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><exclusions><exclusion><groupId>org.junit.vintage</groupId><artifactId>junit-vintag…

django實現悲觀鎖樂觀鎖

前期準備 # 線上賣圖書-圖書表 圖書名字&#xff0c;圖書價格&#xff0c;庫存字段-訂單表&#xff1a; 訂單id&#xff0c;訂單名字# 表準備class Book(models.Model):name models.CharField(max_length32)price models.IntegerField() #count models.SmallIntegerField…

Python實時監控鍵盤的輸入并打印出來

要實現Python實時監控鍵盤的輸入并打印出來&#xff0c;可以使用pynput模塊。 首先&#xff0c;需要安裝pynput模塊&#xff1a; pip install pynput 然后&#xff0c;可以編寫以下代碼來實現實時監控鍵盤輸入并打印出來的功能&#xff1a; from pynput import keyboard# 定…

【Unity每日一記】方位辨別—向量的叉乘點乘結合

&#x1f468;?&#x1f4bb;個人主頁&#xff1a;元宇宙-秩沅 &#x1f468;?&#x1f4bb; hallo 歡迎 點贊&#x1f44d; 收藏? 留言&#x1f4dd; 加關注?! &#x1f468;?&#x1f4bb; 本文由 秩沅 原創 &#x1f468;?&#x1f4bb; 收錄于專欄&#xff1a;uni…