【Java】 Java 21 革命性升級:虛擬線程與結構化并發的深度實踐指南

還在為高昂的AI開發成本發愁?這本書教你如何在個人電腦上引爆DeepSeek的澎湃算力!

Java 21 作為 Oracle JDK 的長期支持版本,引入了多項革命性特性,其中虛擬線程(Virtual Threads)和結構化并發(Structured Concurrency)尤為突出。這些特性旨在解決傳統線程模型在高并發場景下的性能瓶頸和編程復雜性。虛擬線程通過輕量級線程實現,使得開發者可以輕松創建數百萬個線程,而無需擔心操作系統資源的消耗;結構化并發則提供了一種更安全、更易管理的并發編程范式,避免了線程泄漏和異常傳播問題。本文將從歷史背景出發,詳細剖析虛擬線程的原理、API 使用和性能優化,結合大量代碼示例和中文注釋進行說明。同時,深入探討結構化并發的核心概念、ScopedValue 和 StructuredTaskScope 等工具的使用場景。通過實際案例和對比分析,幫助讀者理解這些新特性如何提升 Java 應用的并發能力,并探討其在微服務、Web 服務器等領域的應用前景。文章強調實踐導向,提供豐富的代碼片段和解釋,助力開發者快速上手 Java 21 的并發編程革命。總之,這些特性標志著 Java 在并發領域的重大進步,將為現代應用開發注入新活力。

引言:Java 并發編程的演進

Java 自 1995 年誕生以來,并發編程一直是其核心優勢之一。從早期的 synchronized 關鍵字和 Thread 類,到 Java 5 引入的 java.util.concurrent 包(如 ExecutorService、Future 和 Lock),再到 Java 8 的 CompletableFuture 和 Stream API,Java 的并發模型不斷演進。然而,隨著云計算和大數據時代的到來,傳統平臺線程(Platform Threads)模型暴露出了諸多局限性:每個線程都需要操作系統內核的支持,導致創建和管理開銷巨大;在高并發場景下,線程數受限于系統資源,容易引發 OutOfMemoryError 或上下文切換開銷過高的問題。

Java 21(2023 年 9 月發布)作為 LTS(Long-Term Support)版本,引入了虛擬線程和結構化并發這兩大特性,旨在從根本上革新并發編程。虛擬線程是 Project Loom 的成果,它將線程從操作系統內核中解耦,使用 JVM 內部的輕量級調度器管理,從而允許創建海量線程。結構化并發則通過新的 API(如 StructuredTaskScope)提供了一種結構化的任務管理方式,確保子任務的生命周期與父任務綁定,避免了傳統多線程編程中的“野線程”問題。

本文將深入探討這些特性。首先,我們將介紹虛擬線程的背景和原理,然后通過代碼示例演示其使用。接著,詳解結構化并發,并結合實際場景進行分析。為了便于理解,我們會提供大量帶有中文注釋的 Java 代碼,并解釋每個部分的實現邏輯。如果涉及性能建模,我們會使用 LaTeX 公式進行表示,例如線程切換開銷的簡化模型: T s w i t c h = α + β ? N T_{switch} = \alpha + \beta \cdot N Tswitch?=α+β?N,其中 (\alpha) 是固定開銷,(\beta) 是每個線程的額外成本,(N) 是線程數。

第一部分:虛擬線程的原理與實現

1.1 虛擬線程的背景

傳統 Java 線程是基于操作系統線程的 1:1 映射模型,每個 Java 線程對應一個內核線程。這導致了幾個問題:

  • 資源消耗高:內核線程需要棧空間(通常 1MB 以上)和調度資源,限制了線程總數(典型服務器上不超過幾千個)。
  • 上下文切換開銷:當線程阻塞(如 I/O 操作)時,內核需要保存和恢復上下文,消耗 CPU 時間。
  • 編程模型復雜:開發者往往使用線程池來復用線程,但這引入了異步編程的復雜性,如回調地獄或 Reactive Streams。

Project Loom 旨在引入 Go 語言式的 Goroutines 或 Kotlin 的 Coroutines 類似機制:虛擬線程(Virtual Threads)。虛擬線程是 JVM 管理的用戶模式線程,與內核線程是 M:N 映射(多個虛擬線程映射到少量內核線程)。當虛擬線程阻塞時,JVM 可以將其“掛起”到堆上,而不阻塞內核線程,從而實現高效的并發。

在 Java 21 中,虛擬線程通過 Thread.ofVirtual() 創建,默認棧大小僅為傳統線程的幾分之一。性能測試顯示,虛擬線程可以輕松處理數百萬并發任務,而傳統線程在數千個時就崩潰。

1.2 虛擬線程的 API 使用

虛擬線程的創建非常簡單。以下是基本示例:

// 導入必要的包
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;public class VirtualThreadDemo {public static void main(String[] args) {// 創建虛擬線程工廠ThreadFactory virtualFactory = Thread.ofVirtual().factory();// 使用 Executors 創建執行器服務try (var executor = Executors.newThreadPerTaskExecutor(virtualFactory)) {// 提交 10000 個任務,每個任務模擬 I/O 操作for (int i = 0; i < 10000; i++) {final int taskId = i;executor.submit(() -> {try {// 模擬阻塞操作,如網絡調用Thread.sleep(1000);System.out.println("任務 " + taskId + " 完成,由虛擬線程執行: " + Thread.currentThread().getName());} catch (InterruptedException e) {Thread.currentThread().interrupt();}});}} // executor 會自動關閉System.out.println("所有任務提交完成");}
}

在這個代碼中,我們使用 Thread.ofVirtual().factory() 創建虛擬線程工廠,然后通過 Executors.newThreadPerTaskExecutor() 為每個任務創建一個新虛擬線程。注意,try-with-resources 確保 executor 關閉。每個任務使用 Thread.sleep() 模擬阻塞,這在虛擬線程中不會阻塞底層內核線程。

解釋:傳統線程池(如 Executors.newFixedThreadPool(10))會限制線程數為 10,導致任務排隊。而在虛擬線程中,我們可以提交 10000 個任務,每個都有自己的線程,但實際內核線程只有少數幾個(通常等于 CPU 核心數)。這大大提高了吞吐量。

1.3 虛擬線程的性能分析

虛擬線程的性能優勢可以用數學模型表示。假設傳統線程的上下文切換開銷為 C t r a d = k ? N C_{trad} = k \cdot N Ctrad?=k?N,其中 (k) 是常量,(N) 是線程數。對于虛擬線程,當阻塞時,開銷接近零,因為 JVM 使用 continuation(延續)機制保存狀態: C v i r t = m ? P C_{virt} = m \cdot P Cvirt?=m?P,其中 (m < k),(P) 是活躍線程數(遠小于 (N))。

以下代碼演示性能對比:我們創建 100000 個線程,測量時間。

import java.time.Duration;
import java.time.Instant;
import java.util.concurrent.CountDownLatch;public class PerformanceCompare {public static void main(String[] args) throws InterruptedException {testVirtualThreads(100000);testPlatformThreads(100000); // 注意:這可能導致 OOM}private static void testVirtualThreads(int count) throws InterruptedException {Instant start = Instant.now();CountDownLatch latch = new CountDownLatch(count);ThreadFactory factory = Thread.ofVirtual().factory();for (int i = 0; i < count; i++) {Thread thread = factory.newThread(() -> {try {// 模擬工作Thread.

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

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

相關文章

Apache IoTDB 全場景部署:基于 Apache IoTDB 的跨「端-邊-云」的時序數據庫 DB+AI

Apache IoTDB 全場景部署&#xff1a;基于 Apache IoTDB 的跨「端-邊-云」的時序數據庫 DBAI 文章目錄Apache IoTDB 全場景部署&#xff1a;基于 Apache IoTDB 的跨「端-邊-云」的時序數據庫 DBAIApache IoTDB 介紹Docker部署指導企業版數據庫配套工具 WorkbenchTimechoDB&…

計算機網絡---傳輸控制協議Transmission Control Protocol(TCP)

一、TCP的定位與核心特性 TCP&#xff08;Transmission Control Protocol&#xff0c;傳輸控制協議&#xff09;是TCP/IP協議棧中傳輸層的核心協議&#xff0c;與UDP&#xff08;用戶數據報協議&#xff09;共同承擔端到端數據傳輸功能。其設計目標是在不可靠的IP網絡上提供可靠…

week1-[分支嵌套]公因數

week1-[分支嵌套]公因數 題目描述 給定 444 個正整數 a,b,c,ka,b,c,ka,b,c,k。如果 a,b,ca,b,ca,b,c 都是 kkk 的倍數&#xff0c;那么稱 kkk 是 a,b,ca,b,ca,b,c 的公因數。否則如果某兩個數都是 kkk 的倍數&#xff0c;那么稱 kkk 是這兩個數的公因數。問 kkk 是哪些數的公因…

C#枚舉/結構體講一講

先展示一段簡單代碼// 定義枚舉 public enum thisday {吃飯,不吃 }// 定義結構體 public struct person {public string name;public int age;public thisday zhuangtai; // 使用枚舉類型作為字段 }static void Main(string[] args) {// 創建結構體實例person thisperson;thisp…

C++-setmap詳解

Cset&map 1. 序列式容器和關聯式容器 1.1 序列式容器 序列式容器按照線性順序存儲元素&#xff0c;元素的位置取決于插入的時間和位置&#xff0c;與元素的值無關。 主要特點&#xff1a;元素按插入順序存儲可以通過位置&#xff08;索引&#xff09;直接訪問元素不自動排序…

解決程序連不上RabbitMQ:Attempting to connect to/access to vhost虛擬主機掛了的排錯與恢復

前言&#xff1a;在分布式系統里&#xff0c;RabbitMQ作為消息中間件&#xff0c;是服務間通信的關鍵紐帶。但實際使用中&#xff0c;程序連接RabbitMQ失敗的情況時有發生。本文結合真實報錯&#xff0c;細致呈現從問題發現到解決的完整排錯思路&#xff0c;還會深入講解Rabbit…

K8S中如何配置PDB(Pod Disruption Budget)

1. PDB 核心概念作用&#xff1a;控制自愿中斷&#xff08;如節點升級、縮容&#xff09;期間&#xff0c;應用的最小可用副本數或最大不可用比例。關鍵參數&#xff1a;minAvailable&#xff1a;必須保持運行的 Pod 數量&#xff08;如 2 或 50%&#xff09;。maxUnavailable&…

從 0 到 1:用 MyCat 打造可水平擴展的 MySQL 分庫分表架構

一、為什么要分庫分表&#xff1f; 單機 MySQL 的極限大致在&#xff1a;維度經驗值單表行數≤ 1 000 萬行&#xff08;B 樹三層&#xff09;單庫磁盤≤ 2 TB&#xff08;SSD&#xff09;單機 QPS≤ 1 萬&#xff08;InnoDB&#xff09;當業務繼續增長&#xff0c;數據量和并發…

電池模組奇異值分解降階模型

了解如何將奇異值分解 (SVD) 降階模型 (ROM) 應用于電池模塊熱模擬。挑戰隨著電池模塊在電動汽車和儲能系統中的重要性日益提升&#xff0c;其熱性能管理也成為一項重大的工程挑戰。高功率密度會產生大量熱量&#xff0c;如果散熱不當&#xff0c;可能導致電池性能下降、性能下…

《Python函數:從入門到精通,一文掌握函數編程精髓》

堅持用 清晰易懂的圖解 代碼語言&#xff0c;讓每個知識點變得簡單&#xff01; &#x1f680;呆頭個人主頁詳情 &#x1f331; 呆頭個人Gitee代碼倉庫 &#x1f4cc; 呆頭詳細專欄系列 座右銘&#xff1a; “不患無位&#xff0c;患所以立。” Python函數&#xff1a;從入門到…

【記錄貼】STM32 I2C 控制 OLED 卡死?根源在 SR1 與 SR2 的讀取操作

問題描述最近在復用以前STM32F407控制OLED的代碼&#xff0c;移植到STM32F103 上&#xff0c;使用硬件 I2C 通信方式。按照常規流程&#xff0c;先發送 OLED 的從機地址&#xff0c;OLED 有正常應答&#xff0c;但當發送第一個控制命令&#xff08;0xAE&#xff09;前的控制字節…

【AI驅動的語義通信:突破比特傳輸的下一代通信范式】

文章目錄1 語義通信簡介1.1 基本概念&#xff1a;什么是語義通信&#xff1f;語義通信的核心目標1.2 基本結構&#xff1a;語義通信系統結構語義通信系統的通用結構組成語義通信系統的結構關鍵模塊1.3 基于大模型的語義通信關鍵技術&#x1f9e0;語義通信系統中AI大模型的設計建…

網絡原理-HTTP

應用層自定義協議自定義協議是指根據特定需求設計的通信規則&#xff0c;用于設備或系統間的數據交換。其核心在于定義數據結構、傳輸方式及處理邏輯。協議結構示例典型的自定義協議包含以下部分&#xff1a;頭部&#xff08;Header&#xff09;&#xff1a;標識協議版本、數據…

ROS配置debug指南

一. 安裝插件 下面的這一個插件過期了需要用下面的這一個插件來替換:二. 設置CMakeLists.txt的編譯模式 set(CMAKE_BUILD_TYPE "Debug") set(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g -ggdb") set(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAG…

微軟正式將GPT-5接入Microsoft Copilot Studio(國際版)

微軟宣布正式在Microsoft Copilot Studio&#xff08;國際版&#xff09;中集成GPT-5&#xff0c;推動智能體構建能力實現突破性升級。此次更新不僅為企業用戶帶來更高效的響應速度、更精準的語境理解能力&#xff0c;還通過增強的邏輯推理功能&#xff0c;顯著提升了AI交互的深…

微算法科技(NASDAQ:MLGO)通過蟻群算法求解資源分配的全局最優解,實現低能耗的區塊鏈資源分配

隨著區塊鏈網絡規模的不斷擴大和業務需求的日益復雜&#xff0c;資源分配問題逐漸成為制約其發展的關鍵因素之一。傳統的區塊鏈資源分配方法往往存在效率低下、能耗過高、難以達到全局最優解等問題。高能耗不僅增加了運營成本&#xff0c;還對環境造成了較大的壓力。因此&#…

深入淺出JVM:Java虛擬機的探秘之旅

深入淺出JVM&#xff1a;Java虛擬機的探秘之旅一、JVM 初相識&#xff1a;揭開神秘面紗 在 Java 的世界里&#xff0c;JVM&#xff08;Java Virtual Machine&#xff0c;Java 虛擬機&#xff09;就像是一個神秘的幕后大 boss&#xff0c;掌控著 Java 程序運行的方方面面。你可以…

Nginx學習筆記(八)—— Nginx緩存集成

&#x1f5c4;&#x1f5c4; Nginx緩存集成 &#x1f4cc;&#x1f4cc; 一、緩存核心價值 #mermaid-svg-CNji1KUDOsF8MwoY {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-CNji1KUDOsF8MwoY .error-icon{fill:#5522…

httpx 設置速率控制 limit 時需要注意 timeout 包含 pool 中等待時間

假設通過 httpx.Client 設置 limit 速率控制后&#xff0c;同時發起多個請求訪問 youtube。并且由于科學原因一直連接不上 假設一共 4 個連接&#xff0c;max_connection2&#xff0c;timeout5s。 默認會發生的情況不是前兩個連接 tcp 握手 timeout&#xff0c;后兩個連接再發起…

【網絡】TCP/UDP總結復盤

1.UDP的格式2.TCP的格式3.TCP是來解決什么問題的&#xff1f;答&#xff1a;解決IP層的不可靠傳輸問題&#xff0c;可能數據包丟失、損壞、重復等為上層應用層提高可靠有序的數據傳輸服務通過校驗和、確認應答機制、序列號來解決不可靠傳輸和無序性問題通過流量控制--->>…