我們知道 Go 語言最大亮點之一就是原生支持並發,這得益於 Go 語言的協程機制。一個 go 語句就可以發起一個協程 (goroutin)。
協程本質上是一種用戶態線程,它不需要操作系統來進行調度,而是由用戶程序自行管理和調度。它寄存於線程中,系統開銷極小,可以顯著的提高性能和並發能力。使用協程的優點是運行效率高、編程簡單、結構清晰。目前,原生支持協程的語言不是很多。
Oracle 本周提交的一份JDK增強建議(JEP)草案要求將虛擬線程作為Java標准版的一部分進行預覽。
虛擬線程類似於 Go 語言的協程,將補充Java的平台線程(代表操作系統線程),采用輕量級的用戶模式線程實現,將更有效地利用可用的硬件,並大大降低成本。
虛擬線程目的是更好地支持編寫和維護高吞吐量並發應用程序。
該提案指出,線程對於代表一個並發單元(如事務)是很有用的。Java目前對Thread的實現是為每個Java線程消耗一個操作系統線程,而操作系統線程是稀缺和昂貴的。現代服務器的能力可以處理比操作系統線程更多數量級的並發事務。
編寫高吞吐量服務器軟件的開發者不得不在事務之間共享線程,以有效利用硬件。這是用線程池來完成的,它將線程借給一個又一個事務,以節省為每個事務創建線程的成本。當這還不夠時,開發人員開始將線程返回到線程池中,甚至在事務的中間,在等待I/O的時候。但是,這導致了一種異步的編程風格,需要一套獨立的、不兼容的API,並使故障排除、調試、觀察和分析變得非常困難。
虛擬線程是java.lang.Thread的用戶模式實現,它不會阻塞操作系統線程,能夠實現接近最佳的硬件利用率。虛擬線程允許高水平的並發,以及高吞吐量,同時程序仍然與Java平台和工具的基於線程的設計相協調。虛擬線程對於平台線程來說,就像虛擬內存對於物理RAM一樣:一種通過自動映射到底層物理資源而提供豐富的 "虛擬 "資源的機制。
該提案指出,使用虛擬線程不需要學習新的編程模型。使用Java編寫並發應用程序的開發者已經知道這個模型。然而,開發人員需要改變由於線程的高成本而產生的舊習慣,特別是使用線程池,這些線程池只有在它們所匯集的資源稀缺或創建成本高昂時才有用。
虛擬線程是由JDK實現的java.lang.Thread的實例,它允許許多活動實例在同一進程中共存。虛擬線程的語義與平台線程相同,只是它們屬於單一的ThreadGroup,不能被枚舉。
參考資料:
1. 進程、線程和協程的區別
2. 編程寶庫
