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

當前位置:首頁 > 科技  > 軟件

Java 21 的虛擬線程:高性能并發應用的福音

來源: 責編: 時間:2023-12-08 09:14:12 244觀看
導讀Java 21 最重要的特性之一就是虛擬線程 (JEP 444)。這些輕量級的線程降低了編寫、維護和觀察高吞吐量并行應用所需的努力。在討論新特性之前,讓我們先看一下當前的狀態,以便更好地理解它試圖解決什么問題以及帶來了哪些

Java 21 最重要的特性之一就是虛擬線程 (JEP 444)。這些輕量級的線程降低了編寫、維護和觀察高吞吐量并行應用所需的努力。6xQ28資訊網——每日最新資訊28at.com

在討論新特性之前,讓我們先看一下當前的狀態,以便更好地理解它試圖解決什么問題以及帶來了哪些好處。6xQ28資訊網——每日最新資訊28at.com

平臺線程

在引入虛擬線程之前,我們習慣使用的線程是 java.lang.Thread,它背后是所謂的平臺線程 (platform threads)。6xQ28資訊網——每日最新資訊28at.com

這些線程通常與操作系統調度的內核線程一一映射。操作系統線程相當“重”,這使得它們適合執行所有類型的任務。6xQ28資訊網——每日最新資訊28at.com

根據操作系統和配置,它們默認情況下會消耗大約2到10 MB的內存。因此,如果你想在高負載并發應用程序中使用一百萬個線程,最好要有超過2 TB的可用內存!6xQ28資訊網——每日最新資訊28at.com

這存在一個明顯的瓶頸,限制了我們實際可以在沒有缺點的情況下擁有的線程數量。6xQ28資訊網——每日最新資訊28at.com

每個請求一個線程

這很成問題,因為它直接與典型的服務器應用程序“每個請求一個線程”的方法相沖突。使用每個請求一個線程有很多優點,例如更簡單的狀態管理和清理。但它也創造了可擴展性限制。應用程序的“并發單位”,在這種情況下是一個請求,需要一個“平臺并發單位”。因此,線程很容易被原始CPU能力或網絡耗盡。6xQ28資訊網——每日最新資訊28at.com

即使“每個請求一個線程”有許多優點,共享重量級的線程可以更均勻地利用硬件,但也需要一種完全不同的方法。6xQ28資訊網——每日最新資訊28at.com

異步救援

而不是在單個線程上運行整個請求,它的每個部分都從池中使用一個線程,當它們的任務完成時,另一個任務可能會重用同一個線程。這允許代碼需要更少的線程,但引入了異步編程的負擔。6xQ28資訊網——每日最新資訊28at.com

異步編程伴隨著它自己的范例,具有一定的學習曲線,并且可能會使程序更難理解和跟蹤。請求的每個部分可能都在不同的線程上執行,從而創建沒有合理上下文的堆棧跟蹤,并使調試某些內容變得非常棘手甚至幾乎不可能。6xQ28資訊網——每日最新資訊28at.com

Java有一個用于異步編程的優秀API,CompletableFuture。但這是一個復雜的API,并且不太適合許多Java開發人員習慣的思維方式。6xQ28資訊網——每日最新資訊28at.com

重新審視“每個請求一個線程”模型,很明顯,一種更輕量級的線程方法可以解決瓶頸并提供一種熟悉的做事方式。6xQ28資訊網——每日最新資訊28at.com

輕量級線程

由于平臺線程的數量是無法在沒有更多硬件的情況下改變的,因此需要另一個抽象層,切斷可怕的 1:1 映射,它是首先造成瓶頸的原因。6xQ28資訊網——每日最新資訊28at.com

輕量級線程不與特定的平臺線程綁定,也不會伴隨大量的預分配內存。它們由運行時而不是底層操作系統調度和管理。這就是為什么可以創建大量輕量級線程的原因。6xQ28資訊網——每日最新資訊28at.com

這個概念并不新鮮,許多語言都采用某種形式的輕量級線程:6xQ28資訊網——每日最新資訊28at.com

  • Go 語言中的 Goroutine
  • Erlang 進程
  • Haskell 線程
  • 等等

Java最終于第21版中引入了自己的輕量級線程實現:虛擬線程 (Virtual Threads)。6xQ28資訊網——每日最新資訊28at.com

虛擬線程

虛擬線程是一種新的輕量級java.lang.Thread變體,是Project Loom的一部分,它不是由操作系統管理或調度的。相反,JVM負責調度。6xQ28資訊網——每日最新資訊28at.com

當然,任何實際的工作都必須在平臺線程中運行,但是JVM使用所謂的“載體線程”(carrier threads) 來“攜帶”任何虛擬線程,以便在它們需要執行時執行這些線程。6xQ28資訊網——每日最新資訊28at.com

圖片圖片6xQ28資訊網——每日最新資訊28at.com

JVM/操作系統線程調度器6xQ28資訊網——每日最新資訊28at.com

所需的平臺線程在一個 FIFO 工作竊取 ForkJoinPool 中進行管理,該池默認情況下使用所有可用的處理器,但可以通過調整系統屬性jdk.virtualThreadScheduler.parallelism來根據需求進行修改。6xQ28資訊網——每日最新資訊28at.com

ForkJoinPool與其他功能(例如并行流)使用的通用池之間的主要區別在于,通用池以LIFO模式運行。6xQ28資訊網——每日最新資訊28at.com

廉價且豐富的線程

擁有廉價且輕量級的線程,可以使用“每個請求一個線程”模型,而不必擔心實際需要多少個線程。如果你的代碼在虛擬線程中調用阻塞 I/O 操作,則運行時會掛起虛擬線程,直到它可以稍后恢復。6xQ28資訊網——每日最新資訊28at.com

這樣,硬件就可以被優化到幾乎最佳的水平,從而實現高水平的并發性,因此也實現高吞吐量。6xQ28資訊網——每日最新資訊28at.com

因為它們非常廉價,所以虛擬線程不會被重用或需要池化。每個任務都由其自己的虛擬線程表示。6xQ28資訊網——每日最新資訊28at.com

設置邊界

調度器負責管理載體線程,因此需要一定的邊界和分離,以確保可能的“無數”虛擬線程按照預期運行。這是通過在載體線程及其可能攜帶的任何虛擬線程之間不保持線程關聯來實現的:6xQ28資訊網——每日最新資訊28at.com

  • 虛擬線程無法訪問載體,Thread.currentThread() 返回虛擬線程本身。
  • 堆棧跟蹤是分開的,任何在虛擬線程中拋出的異常只包含其自己的堆棧幀。
  • 虛擬線程的線程局部變量對它的載體不可用,反之亦然。
  • 從代碼的角度來看,載體及其虛擬線程共享一個平臺線程是不可見的。

讓我們看看代碼

使用Virtual Threads最大的好處是,你不需要學習新的范例或復雜的API,就像使用異步編程一樣。相反,你可以像對待非虛擬線程一樣處理它們。6xQ28資訊網——每日最新資訊28at.com

創建平臺線程

創建平臺線程很簡單,就像使用 Runnable 創建一樣:6xQ28資訊網——每日最新資訊28at.com

Runnable fn = () -> {    // your code here};Thread thread = new Thread(fn).start();

隨著Project Loom簡化了新的并發方法,它還提供了一種創建平臺支持線程的新方法:6xQ28資訊網——每日最新資訊28at.com

Thread thread = Thread.ofPlatform().                      .start(runnable);

實際上,現在還有一個完整的fluent API,因為ofPlatform()會返回一個Thread.Builder.OfPlatform實例:6xQ28資訊網——每日最新資訊28at.com

Thread thread = Thread.ofPlatform().                      .daemon()                      .name("my-custom-thread")                      .unstarted(runnable);

但你肯定不是來學習創建“舊”線程的新方法的,我們想要一點新的東西。繼續看。6xQ28資訊網——每日最新資訊28at.com

創建虛擬線程

對于虛擬線程,也有類似的fluent API:6xQ28資訊網——每日最新資訊28at.com

Runnable fn = () -> {  // your code here};Thread thread = Thread.ofVirtual(fn)                      .start();

除了構建器方法之外,你還可以直接使用以下方式執行Runnable:6xQ28資訊網——每日最新資訊28at.com

Thread thread = Thread.startVirtualThread(() -> {  // your code here});

由于所有虛擬線程始終是守護線程,因此如果你想在主線程上等待,請不要忘記調用join()。6xQ28資訊網——每日最新資訊28at.com

創建虛擬線程的另一種方法是使用 Executor:6xQ28資訊網——每日最新資訊28at.com

var executorService = Executors.newVirtualThreadPerTaskExecutor();executorService.submit(() -> {  // your code here});

小結

盡管Scoped Values (JEP 446) 和Structured Concurrency (JEP 453) 仍然是Java 21中的預覽功能,但Virtual Threads已經成為一個成熟的、適用于生產環境的功能。6xQ28資訊網——每日最新資訊28at.com

它們是Java并發的一種通用且強大的新方法,將對我們未來的程序產生重大影響。它們使用了熟悉的和可靠的“每個請求一個線程”方法,同時以最優化的方式利用所有可用硬件,而不需要學習新的范例或復雜的API。6xQ28資訊網——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-39505-0.htmlJava 21 的虛擬線程:高性能并發應用的福音

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

上一篇: 你 UTF-8 亂碼,關我 Unicode 什么事

下一篇: 一款小而美的開源滑動驗證碼組件

標簽:
  • 熱門焦點
Top 主站蜘蛛池模板: 红原县| 江达县| 牡丹江市| 常熟市| 琼结县| 中山市| 屏山县| 义马市| 嘉祥县| 永川市| 淳安县| 扶余县| 筠连县| 延川县| 龙门县| 迁安市| 南陵县| 读书| 阜阳市| 琼中| 通海县| 德清县| 安岳县| 怀化市| 桃园市| 山西省| 莲花县| 万载县| 仪征市| 黄山市| 安新县| 呼图壁县| 临洮县| 稷山县| 邯郸市| 丽江市| 瑞昌市| 青川县| 乳山市| 防城港市| 南岸区|