使用Loom建立虛擬執行緒 - david
在這篇文章中,我們展示如何使用Loom實現類似Go語言的綠色虛擬執行緒。
Project loom 仍處於預覽階段,這意味著 api 可能隨時更改。如果您想自己嘗試這些示例,可使用Early-access build 19-loom+4-115 (2022/2/13) 製作的。
引入虛擬執行緒
Java 中的執行緒只是由作業系統管理和排程的執行緒的一個小包裝器。Project Loom 向 Java 新增了一種稱為虛擬執行緒的新型執行緒,這些執行緒由 JVM 管理和排程。
要建立平臺執行緒(由作業系統管理的執行緒),您需要進行系統呼叫,而且這些呼叫成本很高。要建立虛擬執行緒,您不必進行任何系統呼叫,從而使這些執行緒在您需要時可以很便宜地製作。這些虛擬執行緒在載體執行緒上執行。在幕後,JVM 建立了一些平臺執行緒供虛擬執行緒執行。由於我們沒有系統呼叫和上下文切換,我們可以在幾個平臺執行緒上執行數千個虛擬執行緒。
建立虛擬執行緒
建立虛擬執行緒的最簡單方法是使用Thread類。使用 Loom,我們獲得了一個新的 builder 方法和 factory 方法來建立虛擬執行緒。
Runnable task = () -> System.out.println("Hello, world"); // Platform thread (new Thread(task)).start(); Thread platformThread = new Thread(task); platformThread.start(); // Virtual thread Thread virtualThread = Thread.startVirtualThread(task); Thread ofVirtualThread = Thread.ofVirtual().start(task); // Virtual thread created with a factory ThreadFactory factory = Thread.ofVirtual().factory(); Thread virtualThreadFromAFactory = factory.newThread(task); virtualThreadFromAFactory.start(); |
這個例子首先向我們展示瞭如何建立一個平臺執行緒,接著是一個虛擬執行緒的例子。虛擬執行緒和平臺執行緒都以Runnable為引數,並返回一個執行緒的例項。此外,啟動一個虛擬執行緒與我們習慣於通過呼叫start()方法來啟動平臺執行緒是一樣的。
用Concurrency API建立虛擬執行緒
Loom還為Concurrency API新增了一個新的執行器來建立新的虛擬執行緒。新的VirtualThreadPerTaskExecutor返回一個實現ExecutorService介面的執行器,就像其他執行器那樣。讓我們先來看看使用Executors.newVirtualThreadPerTaskExecutor()方法來獲得一個使用虛擬執行緒的ExecutorService的例子。
Runnable task = () -> System.out.println("Hello, world"); ExecutorService executorService = Executors.newVirtualThreadPerTaskExecutor(); executorService.execute(task); |
正如你所看到的,它看起來與現有的執行器並無不同。在這個例子中,我們使用Executors.newVirtualThreadPerTaskExecutor()來建立一個ExecutorService。這個虛擬執行緒執行器在一個新的虛擬執行緒上執行每個任務。由VirtualThreadPerTaskExecutor建立的執行緒的數量是沒有限制的。
我可以使用現有的執行緒執行器executors嗎?
簡短的回答是可以的,你可以通過給他們提供一個虛擬執行緒工廠來使用現有的執行器與虛擬執行緒。請記住,這些執行器是為了彙集執行緒而建立的,因為平臺執行緒的建立成本很高。使用一個彙集執行緒的執行器與虛擬執行緒結合起來可能是可行的,但這有點忽略了虛擬執行緒的意義。你不需要彙集它們,因為它們的建立成本很低。
ThreadFactory factory = Thread.ofVirtual().factory(); Executors.newVirtualThreadPerTaskExecutor(); Executors.newThreadPerTaskExecutor(factory); // Same as newVirtualThreadPerTaskExecutor Executors.newSingleThreadExecutor(factory); Executors.newCachedThreadPool(factory); Executors.newFixedThreadPool(1, factory); Executors.newScheduledThreadPool(1, factory); Executors.newSingleThreadScheduledExecutor(factory); |
在第一行,我們建立了一個虛擬執行緒工廠,它將處理執行器的執行緒建立問題。接下來,我們為每個執行器呼叫new方法,併為其提供我們剛剛建立的工廠。注意,用虛擬執行緒工廠呼叫newThreadPerTaskExecutor與直接呼叫newVirtualThreadPerTaskExecutor是一樣的。
Completable future
當我們使用CompletableFuture時,我們儘量在呼叫get之前將我們的動作串聯chain化,因為呼叫get會阻塞執行緒。有了虛擬執行緒,呼叫get就不會再阻塞執行緒了。沒有了使用get的懲罰,你可以隨時使用它,而不必寫非同步程式碼。這使得編寫和閱讀Java程式碼變得更加容易。
結構化的併發性
由於執行緒的建立成本很低,Project Loom還為Java帶來了結構化的併發性。通過結構化併發,你將執行緒的生命週期與一個程式碼塊繫結。在你的程式碼塊中,你建立你需要的執行緒,並在所有執行緒完成或停止時離開該程式碼塊。
System.out.println("---------"); try (ExecutorService e = Executors.newVirtualThreadPerTaskExecutor()) { e.submit(() -> System.out.println("1")); e.submit(() -> System.out.println("2")); } System.out.println("---------"); |
Try-with-resources語句可以使用ExecutorService,因為Project Loom用AutoCloseable介面擴充套件了Executor。在try中,我們提交所有需要完成的任務,一旦執行緒完成,我們就離開try。控制檯中的輸出將看起來像這樣。
--------- 2 1 --------- |
第二條虛線將永遠不會被列印在數字之間,因為該執行緒在等待try-with-resources的完成。
總結
該專案仍處於預覽階段,在我們看到它投入生產之前,API可能會發生變化。但探索新的API,看看它已經給我們帶來了哪些效能上的改進,還是很不錯的。
相關文章
- 使用JDK16支援的Loom虛擬執行緒的代價 – WebtideJDKOOM執行緒WebIDE
- project-loom-c5m:用Project Loom虛擬執行緒實現500萬長連線的實驗ProjectOOM執行緒
- 【unity】 Loom實現多執行緒UnityOOM執行緒
- Java 21 虛擬執行緒:使用指南(一)Java執行緒
- [Java基礎]虛擬執行緒Java執行緒
- 虛擬執行緒原理及效能分析執行緒
- Java 21 神仙特性:虛擬執行緒使用指南(一)Java執行緒
- 3 分鐘理解 Java 虛擬執行緒Java執行緒
- java 21 虛擬執行緒初體驗Java執行緒
- 使用 Jetty 12 演示 Ktor 中的虛擬執行緒支援Jetty執行緒
- Java 18中啟動Project Loom數百萬執行緒JavaProjectOOM執行緒
- 聊聊JDK19特性之虛擬執行緒JDK執行緒
- Java“虛擬執行緒”被提交到JEP草案Java執行緒
- [深入理解Java虛擬機器]執行緒Java虛擬機執行緒
- 支援JDK19虛擬執行緒的web框架,之四:看原始碼,瞭解quarkus如何支援虛擬執行緒JDK執行緒Web框架原始碼
- 多執行緒------執行緒與程式/執行緒排程/建立執行緒執行緒
- 使用CreateThreadPool建立執行緒池thread執行緒
- 使用Executors建立和管理執行緒執行緒
- MFC多執行緒的建立,包括工作執行緒和使用者介面執行緒執行緒
- 執行緒的建立及執行緒池執行緒
- Java 21 正式 GA,虛擬執行緒真的來了Java執行緒
- Java 21 新特性:虛擬執行緒(Virtual Threads)Java執行緒thread
- Java中CompletableFuture與虛擬執行緒比較Java執行緒
- 執行緒池建立執行緒的過程執行緒
- 認識執行緒、建立執行緒寫法執行緒
- 虛擬執行緒相對於Actor模型或平臺執行緒的主要優勢? - Reddit執行緒模型
- JDK21的虛擬執行緒是什麼?和平臺執行緒什麼關係?JDK執行緒
- 虛擬執行緒原理及效能分析|得物技術執行緒
- Java 21 官方速覽:全面擁抱虛擬執行緒Java執行緒
- Java 21 虛擬執行緒如何限流控制吞吐量Java執行緒
- 執行緒池的建立和使用,執行緒池原始碼初探(篇一)執行緒原始碼
- 使用 ThreadPoolExecutor 建立多執行緒工具類thread執行緒
- Java:使用Executors建立和管理執行緒薦Java執行緒
- 我會手動建立執行緒,為什麼讓我使用執行緒池?執行緒
- 【原創】Java多執行緒初學者指南(3):使用Runnable介面建立執行緒Java執行緒
- Java虛擬機器09——執行緒安全與鎖優化Java虛擬機執行緒優化
- [Java虛擬機器]Java記憶體模型與執行緒Java虛擬機記憶體模型執行緒
- 虛擬執行緒一般應用在哪些場景執行緒