美團面試:JDK21的虛擬線程是什么?和平臺線程什么關系?
虛擬線程(Virtual Thread)是 JDK 而不是 OS 實現(xiàn)的輕量級線程(Lightweight Process,LWP),由 JVM 調度。許多虛擬線程共享同一個操作系統(tǒng)線程,虛擬線程的數(shù)量可以遠大于操作系統(tǒng)線程的數(shù)量。
在引入虛擬線程之前,java.lang.Thread 包已經支持所謂的平臺線程,也就是沒有虛擬線程之前,我們一直使用的線程。JVM 調度程序通過平臺線程(載體線程)來管理虛擬線程,一個平臺線程可以在不同的時間執(zhí)行不同的虛擬線程(多個虛擬線程掛載在一個平臺線程上),當虛擬線程被阻塞或等待時,平臺線程可以切換到執(zhí)行另一個虛擬線程。
虛擬線程、平臺線程和系統(tǒng)內核線程的關系圖如下所示(圖源:How to Use Java 19 Virtual Threads[1]):
關于平臺線程和系統(tǒng)內核線程的對應關系多提一點:在 Windows 和 Linux 等主流操作系統(tǒng)中,Java 線程采用的是一對一的線程模型,也就是一個平臺線程對應一個系統(tǒng)內核線程。Solaris 系統(tǒng)是一個特例,HotSpot VM 在 Solaris 上支持多對多和一對一。具體可以參考 R 大的回答: JVM 中的線程模型是用戶級的么?[2]。
相比較于平臺線程來說,虛擬線程是廉價且輕量級的,使用完后立即被銷毀,因此它們不需要被重用或池化,每個任務可以有自己專屬的虛擬線程來運行。虛擬線程暫停和恢復來實現(xiàn)線程之間的切換,避免了上下文切換的額外耗費,兼顧了多線程的優(yōu)點,簡化了高并發(fā)程序的復雜,可以有效減少編寫、維護和觀察高吞吐量并發(fā)應用程序的工作量。
虛擬線程在其他多線程語言中已經被證實是十分有用的,比如 Go 中的 Goroutine、Erlang 中的進程。
知乎有一個關于 Java 19 虛擬線程的討論,感興趣的可以去看看:https://www.zhihu.com/question/536743167 。
Java 虛擬線程的詳細解讀和原理可以看下面這兩篇文章:
-
Java19 正式 GA!看虛擬線程如何大幅提高系統(tǒng)吞吐量 -
虛擬線程 - VirtualThread 源碼透視[3]
虛擬線程在 Java 19 中進行了第一次預覽,由JEP 425[4]提出。JDK 20 中是第二次預覽,做了一些細微變化,JDK21 中順利轉正。
最后,我們來看一下四種創(chuàng)建虛擬線程的方法:
// 1、通過 Thread.ofVirtual() 創(chuàng)建
Runnable fn = () -> {
// your code here
};
Thread thread = Thread.ofVirtual(fn)
.start();
// 2、通過 Thread.startVirtualThread() 、創(chuàng)建
Thread thread = Thread.startVirtualThread(() -> {
// your code here
});
// 3、通過 Executors.newVirtualThreadPerTaskExecutor() 創(chuàng)建
var executorService = Executors.newVirtualThreadPerTaskExecutor();
executorService.submit(() -> {
// your code here
});
//
class CustomThread implements Runnable {
@Override
public void run() {
System.out.println("CustomThread run");
}
}
//4、通過 ThreadFactory 創(chuàng)建
CustomThread customThread = new CustomThread();
// 獲取線程工廠類
ThreadFactory factory = Thread.ofVirtual().factory();
// 創(chuàng)建虛擬線程
Thread thread = factory.newThread(customThread);
// 啟動線程
thread.start();
通過上述列舉的 4 種創(chuàng)建虛擬線程的方式可以看出,官方為了降低虛擬線程的門檻,盡力復用原有的 Thread 線程類,這樣可以平滑的過渡到虛擬線程的使用。
參考資料
How to Use Java 19 Virtual Threads: https://medium.com/javarevisited/how-to-use-java-19-virtual-threads-c16a32bad5f7
[2]JVM 中的線程模型是用戶級的么?: https://www.zhihu.com/question/23096638/answer/29617153
[3]虛擬線程 - VirtualThread 源碼透視: https://www.cnblogs.com/throwable/p/16758997.html
[4]JEP 425: https://openjdk.org/jeps/425
·············· END ··············
??專屬面試小冊/一對一提問/簡歷修改/專屬求職指南/學習打卡,歡迎加入 JavaGuide 官方知識星球 (內附星球專屬優(yōu)惠券)。
?? 近期文章精選:

