Java“虛擬執行緒”被提交到JEP草案

banq發表於2021-11-16

Java也終於要有纖程、綠色執行緒啦,虛擬執行緒能大幅減少編寫、維護和觀察高吞吐量併發應用程式的工作量,這些應用程式通過虛擬執行緒充分利用可用硬體,這是一種成本顯著降低的輕量級使用者模式執行緒實現。這是一個預覽功能

目標

  • 新增java.lang.Thread指定虛擬執行緒的附加實現,它將擴充套件到幾 GB 堆上的數百萬個活動例項,並表現出與現有執行緒(指定平臺執行緒)幾乎相同的行為。
  • 通過現有的 JDK 工具和工具介面,以儘可能類似於平臺執行緒的方式支援虛擬執行緒的故障排除、除錯和分析。

在過去的幾十年中,開發人員一直廣泛使用 Java 來編寫併發應用程式,例如伺服器和執行緒,特別是 java.lang.Thread,已成為他們的核心構建塊。執行緒可以很好地表示併發的某些應用程式單元,例如事務,因為平臺及其工具知道並跟蹤它。

不幸的是,當前的 Thread 實現為每個 Java 執行緒消耗一個 OS 執行緒,而 OS 執行緒稀缺且成本高昂,遠比套接字Socket多得多。這意味著現代伺服器可以處理比作業系統執行緒多幾個數量級的併發事務。

編寫高吞吐量伺服器軟體的開發人員必須有效利用硬體以免浪費它,因此必須在事務之間共享執行緒。

首先通過使用執行緒池將執行緒借給事務以節省為每個執行緒建立新執行緒的成本,然後,如果這還不夠,因為作業系統根本無法支援儘可能多的併發執行緒;這導致了非同步程式設計風格,它不僅需要一組單獨且不相容的 API,而且打破了邏輯應用程式單元(事務)和平臺單元(執行緒)之間的連線,這使得平臺不知道應用程式的邏輯單位。結果,故障排除、觀察、除錯和分析變得非常困難,因為平臺的上下文——執行緒——不再代表事務,因此不是很有用。為更困難的開發和維護購買更好的硬體利用率,這也轉化為浪費。

然後,開發人員被迫在將併發的邏輯單元直接建模為執行緒的自然風格和浪費其硬體可以支援的大量吞吐量之間進行選擇。

虛擬執行緒——使用者模式實現java.lang.Thread——給我們兩全其美的。在虛擬執行緒上使用相同的同步 API 時,這些廉價執行緒會阻塞,而不會阻塞任何寶貴的作業系統執行緒。硬體利用率接近最佳,允許高水平的併發性,從而實現高吞吐量,同時程式與 Java 平臺的基於執行緒的設計及其工具保持和諧。

虛擬執行緒之於平臺執行緒,就像虛擬記憶體之於物理 RAM:一種機制,通過自動有效地對映到底層“物理”資源,產生大量“虛擬”資源的錯覺。

由於虛擬執行緒既便宜又豐富,執行緒使用模式預計會發生變化。

 

虛擬執行緒是 JDK 實現的 java.lang.Thread 的例項,它允許大量活動例項在同一程式中共存。它們可以使用java.lang.Thread.Builder介面建立,如下所示:

Thread thread = Thread.ofVirtual().name("duke").unstarted(runnable);

可以通過該Thread::isVirtual方法查詢執行緒是否為虛擬執行緒。

JDK 通過在 Java 堆上儲存它們的狀態(包括堆疊)來實現虛擬執行緒。虛擬執行緒由Java類庫中的排程器進行排程,其工作執行緒在虛擬執行緒執行時將虛擬執行緒掛載在其上,從而成為它們的載體;當虛擬執行緒掛起時:比如說,當它阻塞在一些 I/O 操作或 java.util.concurrent 同步構造上時,而同時這些虛擬執行緒的載體可以自由地執行任何其他任務。

當一個虛擬執行緒被從掛起狀態解放恢復執行時,比如說,一個 I/O 操作已經完成,它就會被提交給排程程式,當其可用時,將在某個載體執行緒上掛載和恢復這個虛擬執行緒,不一定是它在之前執行的同一工作執行緒。這樣,當一個虛擬執行緒執行阻塞操作時,就不會阻塞一個OS工作執行緒。

詳細點選標題

 

相關文章