日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當(dāng)前位置:首頁 > 科技  > 軟件

響應(yīng)式編程又變天了?看JDK21虛擬線程如何顛覆!

來源: 責(zé)編: 時間:2024-01-02 09:32:06 255觀看
導(dǎo)讀命令式風(fēng)格編程一直深受開發(fā)者喜愛,如 if-then-else、while 循環(huán)、函數(shù)和代碼塊等結(jié)構(gòu)使代碼易理解、調(diào)試,異常易追蹤。然而,像所有好的東西一樣,通常也有問題。這種編程風(fēng)格導(dǎo)致線程被阻塞時間遠超過必要時間。1 同步阻

命令式風(fēng)格編程一直深受開發(fā)者喜愛,如 if-then-else、while 循環(huán)、函數(shù)和代碼塊等結(jié)構(gòu)使代碼易理解、調(diào)試,異常易追蹤。然而,像所有好的東西一樣,通常也有問題。這種編程風(fēng)格導(dǎo)致線程被阻塞時間遠超過必要時間。sm428資訊網(wǎng)——每日最新資訊28at.com

1 同步阻塞設(shè)計

1.1 同步阻塞設(shè)計的線程圖

為了便于你理解,讓我們看一個典型的企業(yè)用例請求:sm428資訊網(wǎng)——每日最新資訊28at.com

  • 從DB獲取數(shù)據(jù)
  • 從 Web 服務(wù)獲取數(shù)據(jù)
  • 合并結(jié)果并將最終合并的結(jié)果發(fā)送回用戶

在像 Tomcat 這樣的應(yīng)用服務(wù)器中,一個平臺線程將專用于用戶請求,該線程將繼續(xù)調(diào)用從數(shù)據(jù)庫獲取數(shù)據(jù)的代碼(調(diào)用 FetchDataFromDB),然后調(diào)用從 Web 服務(wù)獲取數(shù)據(jù)的代碼(調(diào)用 FetchDataFromService),然后繼續(xù)合并并將數(shù)據(jù)發(fā)送給用戶(調(diào)用 SendDataToUser)。sm428資訊網(wǎng)——每日最新資訊28at.com

如下圖,將執(zhí)行線程從上到下表示為一個垂直箭頭:sm428資訊網(wǎng)——每日最新資訊28at.com

  • 綠色是執(zhí)行的 CPU 部分
  • 紅色是線程等待數(shù)據(jù)的時間

大多企業(yè)應(yīng)用都是 IO 綁定的,因此線程在大多時間內(nèi)實際是浪費資源。sm428資訊網(wǎng)——每日最新資訊28at.com

圖片圖片sm428資訊網(wǎng)——每日最新資訊28at.com

1.2 評估

Java 中,平臺線程是昂貴資源,因為默認,每個平臺線程消耗 1MB 棧內(nèi)存。即 JVM 中運行的平臺線程數(shù)量有上限。因此,若一個平臺線程專用于用戶請求,對高并發(fā)用戶的應(yīng)用程序,就帶來問題。傳統(tǒng)解決方案是創(chuàng)建一個具有最大線程數(shù)的線程池,并根據(jù)需要水平或垂直擴展應(yīng)用程序:sm428資訊網(wǎng)——每日最新資訊28at.com

  • 垂直擴展意味著向容器或 VM 添加更多資源
  • 水平擴展則意味著添加應(yīng)用程序的更多實例

2 異步阻塞設(shè)計

2.1 異步阻塞設(shè)計線程圖

為了提高性能,可用異步模型,并行運行一些串行任務(wù)。如若假設(shè)數(shù)據(jù)庫和 Web 服務(wù)的獲取任務(wù)可以并行運行,那么它們可以在各自的平臺線程中執(zhí)行。sm428資訊網(wǎng)——每日最新資訊28at.com

圖片圖片sm428資訊網(wǎng)——每日最新資訊28at.com

用戶請求線程啟動兩個線程:sm428資訊網(wǎng)——每日最新資訊28at.com

  • 一個用于處理從數(shù)據(jù)庫獲取數(shù)據(jù)
  • 另一個用于從 Web 服務(wù)獲取數(shù)據(jù)
  • 然后,它將阻塞以獲取兩者結(jié)果,然后繼續(xù)合并并將數(shù)據(jù)發(fā)送給用戶

在 Java 可通過向 Executor Service 提交 Callable 或 Runnable 任務(wù)并使用 Java Futures 來實現(xiàn)。sm428資訊網(wǎng)——每日最新資訊28at.com

2.2 評估

這將提高性能,因為兩個數(shù)據(jù)獲取是并行執(zhí)行的。但是,即使在大多數(shù)時間內(nèi)可能會有性能提升,但是在短時間內(nèi),平臺線程的數(shù)量現(xiàn)在從 1 增加到 3。從可擴展性看,在那段時間內(nèi)情況更壞。sm428資訊網(wǎng)——每日最新資訊28at.com

3 響應(yīng)式樣式設(shè)計

響應(yīng)式編程設(shè)計就是為解決這問題。sm428資訊網(wǎng)——每日最新資訊28at.com

3.1 部分響應(yīng)式設(shè)計線程圖

在于昂貴的平臺線程在阻塞操作期間浪費大部分時間。隨 Servlet 3.0 和 3.1 引入,Servlet 線程在發(fā)送 HTTP 數(shù)據(jù)回用戶時無需保持活動狀態(tài),這為更巧妙編程打開解決線程阻塞的大門。Java 8 CompletableFuture類可在其中創(chuàng)建響應(yīng)式管道。這種開發(fā)風(fēng)格思想是為該用例指定一個執(zhí)行管道,而非執(zhí)行用例本身。sm428資訊網(wǎng)——每日最新資訊28at.com

用戶請求線程只需指定用例的 CompletableFuture 管道(或任何其他管道),并在盡可能短的時間內(nèi)將其釋放回線程池(因為無需再保持活動狀態(tài)以向用戶發(fā)送數(shù)據(jù))。sm428資訊網(wǎng)——每日最新資訊28at.com

圖片圖片sm428資訊網(wǎng)——每日最新資訊28at.com

此時,用戶請求線程創(chuàng)建一個運行 3 個活動的管道:sm428資訊網(wǎng)——每日最新資訊28at.com

  • 先并行運行 FetchDataFromService、FetchDataFromDB
  • 再運行 Send2User

但創(chuàng)建此管道后,用戶請求線程將被簡單釋放回線程池。大大減輕 JVM 負擔(dān),因為現(xiàn)在它有一個較少的線程要處理。一旦數(shù)據(jù)提取線程完成其執(zhí)行,數(shù)據(jù)將被發(fā)送給用戶。sm428資訊網(wǎng)——每日最新資訊28at.com

評估

但這只是部分解決問題,因為從 Web 服務(wù)、DB獲取數(shù)據(jù)的實際活動仍是在它們各自的平臺線程中阻塞。這帶來問題:SE須確保他從管道中生成的任務(wù)不是阻塞的。這很難做到,因為它是手動完成的,并且肯定是錯誤的,因為在編譯時或運行時它不會被標(biāo)記為警告或錯誤。sm428資訊網(wǎng)——每日最新資訊28at.com

4 完全響應(yīng)式樣式設(shè)計

如何才能表現(xiàn)更好?達到更高標(biāo)準(zhǔn) OKR 呢?為使該設(shè)計完全響應(yīng)式,須以非阻塞方式獲取DB、Web 服務(wù)的數(shù)據(jù)。sm428資訊網(wǎng)——每日最新資訊28at.com

作為 JDK 7 的一部分,NIO(New IO) 為非阻塞 IO 打開大門。Java 所有基于 IO 類和方法都有非阻塞版本了。如socket讀/寫、文件讀/寫、鎖 API 等。須使用這些類/方法的非阻塞版本或支持 NIO 的庫來進行數(shù)據(jù)的獲取。sm428資訊網(wǎng)——每日最新資訊28at.com

4.1 完全響應(yīng)式樣式設(shè)計線程圖

圖片圖片sm428資訊網(wǎng)——每日最新資訊28at.com

每個獲取數(shù)據(jù)的 Fetch Data 中,發(fā)出請求的線程和獲取數(shù)據(jù)的線程不同,如:sm428資訊網(wǎng)——每日最新資訊28at.com

  • 從 Web 服務(wù)檢索數(shù)據(jù)的 HTTP GET 請求將在一個線程上運行
  • 而最終處理檢索到的數(shù)據(jù)的線程將在另一個線程上運行

這就是完全響應(yīng)式,它解決了關(guān)鍵問題:IO 操作期間不阻塞。在這里使用平臺線程的唯一時間是在 CPU 操作期間,而不是在 IO 操作期間。在平臺線程的執(zhí)行部分已看不到任何紅色部分。sm428資訊網(wǎng)——每日最新資訊28at.com

這種開發(fā)風(fēng)格能實現(xiàn)應(yīng)用程序高可擴展性。然而,解決方案過復(fù)雜。創(chuàng)建響應(yīng)式管道、調(diào)試它們及想象它們的執(zhí)行很困難。所以很正常,這種開發(fā)風(fēng)格沒有流行開來,只有頂尖的開發(fā)者才對此愛不釋手。Spring Boot 專門用于響應(yīng)式風(fēng)格編程的完整開發(fā)技術(shù)棧即 Spring WebFlux,它使用 Project Reactor 庫提供了對DB、Web 服務(wù)等的非阻塞行為。sm428資訊網(wǎng)——每日最新資訊28at.com

5 虛擬線程

還有響應(yīng)式設(shè)計的其他替代方案嗎?當(dāng)然了!如今 Java 21 的發(fā)布,Oracle 推出備受期待的 Virtual Threads 功能。sm428資訊網(wǎng)——每日最新資訊28at.com

平臺線程問題是在阻塞操作期間,實際變得無用。平臺線程基本是os線程的簡易包裝,畢竟os線程是昂貴的。sm428資訊網(wǎng)——每日最新資訊28at.com

而虛擬線程是 JVM 中 Thread 類的實現(xiàn),它是輕量級的。最終歸結(jié)為以下幾點 — 當(dāng)使用虛擬線程進行代碼執(zhí)行時,它將在 CPU 操作期間使用平臺線程(稱為載體線程),并且在遇到 IO 操作時將載體線程釋放。sm428資訊網(wǎng)——每日最新資訊28at.com

JVM如何知道何時遇到 IO 操作?

虛擬線程中運行時,JVM 將自動切換到使用 IO 操作的非阻塞版本。這種更改已在大多核心 Java 類庫中為大多數(shù) IO 操作進行了痛苦修改。當(dāng)代碼遇到 IO 操作,載體線程將被釋放,并且在該 IO 的數(shù)據(jù)可用時,虛擬線程將被重新安排在另一個載體線程上處理數(shù)據(jù)。即在虛擬線程中阻塞不是問題,因為底層的載體線程被釋放了。sm428資訊網(wǎng)——每日最新資訊28at.com

SE現(xiàn)在可選擇使用虛擬線程進行用戶請求。即SE可繼續(xù)使用與以前相同的命令式開發(fā)風(fēng)格,同時獲得使用響應(yīng)式管道時獲得的可擴展性優(yōu)勢(但沒有復(fù)雜性)。sm428資訊網(wǎng)——每日最新資訊28at.com

具有虛擬線程的同步阻塞線程圖

這種方式在同步阻塞設(shè)計中的情況(注意,阻塞不是一個問題)。sm428資訊網(wǎng)——每日最新資訊28at.com

圖片圖片sm428資訊網(wǎng)——每日最新資訊28at.com

用戶請求線程是虛擬線程(藍色垂直箭頭)。線程上的紅色不再是問題,因為阻塞操作期間,底層的載體線程將被釋放,從而實現(xiàn)與使用響應(yīng)式框架相同的可擴展性優(yōu)勢。sm428資訊網(wǎng)——每日最新資訊28at.com

6 虛擬線程和異步阻塞設(shè)計

6.1 異步阻塞設(shè)計中的虛擬線程

阻塞在此也不再是問題。前面提到可用 Java Futures 實現(xiàn),我們確實有這樣做的選擇。但Java 21引入 StructuredTaskScope 和 Subtask ,以處理結(jié)構(gòu)化異步行為。sm428資訊網(wǎng)——每日最新資訊28at.com

圖片圖片sm428資訊網(wǎng)——每日最新資訊28at.com

虛擬線程 和 StructuredTaskScope 的組合將非常強大。虛擬線程使阻塞不再是一個問題,而 StructuredTaskScope 將為我們提供更高級別的類,以直觀的方式處理異步編程。很難看到為什么還需要 Completable Futures。sm428資訊網(wǎng)——每日最新資訊28at.com

虛擬線程 V.S 響應(yīng)式框架

  • 可繼續(xù)使用命令式風(fēng)格開發(fā)
  • 無需創(chuàng)建復(fù)雜的響應(yīng)式管道
  • 無需在代碼中直接使用非阻塞 IO
  • 更易編碼、調(diào)試和理解

7 總結(jié)

隨著 Java 21 中 虛擬線程 引入,虛擬線程在阻塞狀態(tài)下不再是問題。開發(fā)人員:sm428資訊網(wǎng)——每日最新資訊28at.com

  • 無需創(chuàng)建復(fù)雜的響應(yīng)式風(fēng)格管道
  • 且無需在代碼中直接使用非阻塞 IO

即可創(chuàng)建高度可擴展的應(yīng)用程序。替代方案是使用 Java 21 中引入的 虛擬線程 與 Java Futures 或 Structured Concurrency(Java 21 中的預(yù)覽功能) 類的組合。sm428資訊網(wǎng)——每日最新資訊28at.com

參考:sm428資訊網(wǎng)——每日最新資訊28at.com

  • 編程嚴(yán)選網(wǎng)

本文鏈接:http://www.www897cc.com/showinfo-26-55377-0.html響應(yīng)式編程又變天了?看JDK21虛擬線程如何顛覆!

聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權(quán)等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: 快速上手:使用 Python 連接 SQL Server 數(shù)據(jù)庫并實時讀取數(shù)據(jù)?

下一篇: 響應(yīng)式編程又變天了?看JDK21虛擬線程如何顛覆!

標(biāo)簽:
  • 熱門焦點
Top 主站蜘蛛池模板: 济南市| 高淳县| 乡城县| 沁源县| 阿尔山市| 丽江市| 建昌县| 吐鲁番市| 偏关县| 汉沽区| 太湖县| 托克托县| 青铜峡市| 平果县| 五指山市| 西盟| 吉林市| 平谷区| 武胜县| 宣城市| 光泽县| 柏乡县| 镇江市| 南阳市| 江安县| 兴安县| 衡阳市| 余庆县| 周至县| 民权县| 遂川县| 固阳县| 灵台县| 威海市| 安义县| 锡林浩特市| 天门市| 河南省| 绵阳市| 克山县| 汉寿县|