首先了解一個理念:線程與 OS 線程 1:1 綁定
在傳統 Java 線程(平臺線程)模型中:
每個 Java 線程直接對應一個操作系統級別的線程
操作系統負責調度這些線程
線程的創建、管理和調度都由操作系統內核處理
這種模型稱為?1:1 線程模型(一個用戶線程對應一個內核線程)
圖解傳統線程模型
虛擬線程的 M:N?模型
什么是虛擬線程
1. 什么是虛擬線程?
????????虛擬線程是一種輕量級的線程,由JVM管理,而不是操作系統。它們被設計用來顯著減少編寫、維護和觀察高吞吐量并發應用程序的工作量。
????????傳統線程(平臺線程):每個線程都直接對應一個操作系統線程(內核線程)。創建大量平臺線程會消耗大量系統資源(內存和調度開銷),因此限制了應用程序的并發能力。
????????虛擬線程:它們是用戶模式的線程,由JVM調度,多個虛擬線程可以運行在同一個平臺線程(稱為載體線程)上。虛擬線程的創建和切換成本極低,因此可以創建數百萬個虛擬線程而不會導致系統資源耗盡。
2. 為什么需要虛擬線程?
????????在傳統的“一個請求一個線程”的服務器應用程序中,由于平臺線程的資源限制,通常只能處理數千個并發連接。當有大量I/O等待時(如數據庫調用、網絡請求),線程被阻塞,導致資源浪費。
????????虛擬線程通過以下方式解決:
????????????????高效阻塞:當虛擬線程執行阻塞操作(如I/O)時,它會自動從載體線程上卸載,從而釋放載體線程去執行其他虛擬線程。當阻塞操作完成時,虛擬線程會被調度到某個載體線程上繼續執行。
????????????????高并發:可以創建大量虛擬線程(如百萬級別),使得每個請求可以在自己的虛擬線程中運行,而無需復雜的異步編程模型(如CompletableFuture或反應式編程)。
Java 虛擬線程
前言
????????虛擬線程(Virtual Threads)是 Java 并發模型的革命性創新,在?Java 19?作為預覽特性引入,Java 21?正式發布。這是 Project Loom 的核心成果,旨在解決傳統線程的瓶頸問題。
一、核心問題:傳統線程的局限性
傳統的Java線程
// 傳統線程模型(平臺線程) ExecutorService executor = Executors.newFixedThreadPool(200); for (int i = 0; i < 10_000; i++) {executor.submit(() -> {Thread.sleep(1000); // 模擬I/O阻塞return processRequest();}); }); }
痛點:
線程與 OS 線程 1:1 綁定
創建 10k 線程 → 內存耗盡(1線程≈1MB棧)
上下文切換開銷大(微秒級)
阻塞操作浪費 CPU 資源
一、如何創建虛擬線程
1. 直接創建
?// 1. 使用靜態方法 `Thread.startVirtualThread(Runnable)Thread.startVirtualThread(new Runnable() {@Overridepublic void run() {System.out.println("Hello, Virtual Thread!");}});//2.(推薦使用)使用構建器模式 `Thread.ofVirtual().name("name").start(Runnable)// name方法// - 第一個參數 `"vt-"` 是名稱前綴。//- 第二個參數 `1` 是起始序號。//- 實際生成的線程名稱將是 `"vt-1"`、`"vt-2"`、`"vt-3"` 等,每次創建一個新線程時序號自動增加。Thread vt = Thread.ofVirtual().name("vt-", 1).start(() -> {System.out.println("Running in virtual thread");});
2. 線程池(推薦)
try (ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor()) {for (int i = 0; i < 100_000; i++) {executor.submit(() -> {// 處理請求(含I/O阻塞)return processRequest();});} } // 自動關閉
核心區別對比表
特性 傳統線程(平臺線程) 虛擬線程 與OS關系 1:1 綁定(直接對應OS線程) M:N?映射(JVM管理) 內存開銷 約 1MB/線程(默認棧大小) 約 200B-2KB/線程 創建數量上限 通常數千個 數百萬個 創建速度 毫秒級(涉及OS調用) 微秒級(純JVM操作) 阻塞成本 整個OS線程被阻塞 僅虛擬線程暫停,載體線程釋放 調度器 操作系統內核 JVM(用戶態) 上下文切換 內核介入,開銷大(微秒級) JVM管理,開銷極小(納秒級) 典型使用場景 new Thread()
?或固定大小線程池Thread.ofVirtual().start()
?或虛擬線程池