JDK21的虛擬線程是什麼?和平臺線程什麼關係?

虛擬線程(Virtual Thread)是 JDK 而不是 OS 實現的輕量級線程(Lightweight Process,LWP),由 JVM 調度。許多虛擬線程共享同一個操作系統線程,虛擬線程的數量可以遠大於操作系統線程的數量。

在引入虛擬線程之前,java.lang.Thread 包已經支持所謂的平臺線程,也就是沒有虛擬線程之前,我們一直使用的線程。JVM 調度程序通過平臺線程(載體線程)來管理虛擬線程,一個平臺線程可以在不同的時間執行不同的虛擬線程(多個虛擬線程掛載在一個平臺線程上),當虛擬線程被阻塞或等待時,平臺線程可以切換到執行另一個虛擬線程。

虛擬線程、平臺線程和系統內核線程的關係圖如下所示(圖源:How to Use Java 19 Virtual Threads):

關於平臺線程和系統內核線程的對應關係多提一點:在 Windows 和 Linux 等主流操作系統中,Java 線程採用的是一對一的線程模型,也就是一個平臺線程對應一個系統內核線程。Solaris 系統是一個特例,HotSpot VM 在 Solaris 上支持多對多和一對一。具體可以參考 R 大的回答: JVM 中的線程模型是用戶級的麼?

相比較於平臺線程來說,虛擬線程是廉價且輕量級的,使用完後立即被銷燬,因此它們不需要被重用或池化,每個任務可以有自己專屬的虛擬線程來運行。虛擬線程暫停和恢復來實現線程之間的切換,避免了上下文切換的額外耗費,兼顧了多線程的優點,簡化了高併發程序的複雜,可以有效減少編寫、維護和觀察高吞吐量併發應用程序的工作量。

虛擬線程在其他多線程語言中已經被證實是十分有用的,比如 Go 中的 Goroutine、Erlang 中的進程。

知乎有一個關於 Java 19 虛擬線程的討論,感興趣的可以去看看:https://www.zhihu.com/question/536743167

Java 虛擬線程的詳細解讀和原理可以看下面這幾篇文章:

虛擬線程在 Java 19 中進行了第一次預覽,由JEP 425提出。JDK 20 中是第二次預覽,做了一些細微變化,這裏就不細提了。

最後,我們來看一下四種創建虛擬線程的方法:

// 1、通過 Thread.ofVirtual() 創建
Runnable fn = () -> {
  // your code here
};

Thread thread = Thread.ofVirtual(fn)
                      .start();

// 2、通過 Thread.startVirtualThread() 、創建
Thread thread = Thread.startVirtualThread(() -> {
  // your code here
});

// 3、通過 Executors.newVirtualThreadPerTaskExecutor() 創建
var executorService = Executors.newVirtualThreadPerTaskExecutor();

executorService.submit(() -> {
  // your code here
});

class CustomThread implements Runnable {
  @Override
  public void run() {
    System.out.println("CustomThread run");
  }
}

//4、通過 ThreadFactory 創建
CustomThread customThread = new CustomThread();
// 獲取線程工廠類
ThreadFactory factory = Thread.ofVirtual().factory();
// 創建虛擬線程
Thread thread = factory.newThread(customThread);
// 啓動線程
thread.start(); 

通過上述列舉的 4 種創建虛擬線程的方式可以看出,官方爲了降低虛擬線程的門檻,盡力複用原有的 Thread 線程類,這樣可以平滑的過渡到虛擬線程的使用。

本文已收錄今 JavaGuide (「Java學習 + 面試指南」一份涵蓋大部分 Java 程序員所需要掌握的核心知識)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章