Java21上手體驗-分代ZGC和虛擬執行緒
官方release公告:https://jdk.java.net/21/release-notes
開源中國介紹:https://my.oschina.net/waylau/blog/10112170
新特性一覽:
JEP 431:序列集合
JEP 439:分代 ZGC
JEP 440:記錄模式
JEP 441:switch 模式匹配
JEP 444:虛擬執行緒
JEP 449:棄用 Windows 32 位 x86 移植
JEP 451:準備禁止動態載入代理
JEP 452:金鑰封裝機制 API
JEP 430:字串模板(預覽)
JEP 442:外部函式和記憶體 API(第三次預覽)
JEP 443:未命名模式和變數(預覽)
JEP 445:未命名類和例項主方法(預覽)
JEP 446:作用域值(預覽)
JEP 453:結構化併發(預覽)
JEP 448:Vector API(孵化器第六階段)
其中大家比較關注的是分代 ZGC和虛擬執行緒。
對比17
邊框由不鏽鋼升級為鈦金屬,目錄結構一致:
模組數量比17少一個:
整體大小從289MB增加到了320MB
下載
更新pom
嘗試執行
執行報錯:
java.lang.NoSuchFieldError: Class com.sun.tools.javac.tree.JCTree$JCImport does not have member field 'com.sun.tools.javac.tree.JCTree qualid'
解決辦法:升級lombok至1.18.30
原因:
相容性檢查:
由於我的專案以前用的JDK17,本次升級相容性良好,只發現了一處:
系統托盤中 使用了PopupMenu,出現了字符集問題:
ZGC在之前的JDK版本中也有,這次的分代ZGC更是被大家看好,官方的介紹如下:
Applications running with Generational ZGC should enjoy:
Lower risks of allocations stalls,
Lower required heap memory overhead, and
Lower garbage collection CPU overhead.
Enable Generational ZGC with command line options -XX:+UseZGC -XX:+ZGenerational
使用Java21,使用分代ZGC
MooInfo記憶體佔用檢視
以上只是初步體驗,關於ZGC的更多內容,如詳細的分代回收情況後續進一步探索。
以上記憶體佔用檢視使用我之前做的一個工具,MooInfo:
Virtual threads are lightweight threads that reduce the effort of writing, maintaining, and debugging high-throughput concurrent applications.
虛擬執行緒是輕量級執行緒,可以減少編寫、維護和除錯高吞吐量併發應用程式的工作量。
Oracle介紹原文:
平臺執行緒
Oracle官方文件的機器翻譯:
平臺執行緒是作為作業系統(OS)執行緒的瘦包裝器實現的。
平臺執行緒在其底層作業系統執行緒上執行Java程式碼,平臺執行緒在平臺執行緒的整個生命週期內捕獲其作業系統執行緒。
因此,可用平臺執行緒的數量受限於作業系統執行緒的數量。
平臺執行緒通常有一個大的執行緒堆疊和其他由作業系統維護的資源。
平臺執行緒支援執行緒區域性變數。
平臺執行緒適合執行所有型別的任務,但可能是有限的資源。
Oracle官方文件的機器翻譯:
與平臺執行緒一樣,虛擬執行緒也是 java.lang.Thread 的一個例項。
但是,虛擬執行緒並不依賴於特定的作業系統執行緒。
虛擬執行緒仍然在作業系統執行緒上執行程式碼。
但是,當虛擬執行緒中執行的程式碼呼叫阻塞 I/O 操作時,Java 執行時會掛起虛擬執行緒,直到可以恢復為止。
與掛起的虛擬執行緒關聯的作業系統執行緒現在可以自由地為其他虛擬執行緒執行操作。
實現原理
虛擬執行緒的實現方式與虛擬記憶體類似。
為了模擬大量記憶體,作業系統將較大的虛擬地址空間對映到有限的 RAM。
同樣,為了模擬大量執行緒,Java執行時將大量虛擬執行緒對映到少量作業系統執行緒。
與平臺執行緒不同,虛擬執行緒通常具有淺呼叫堆疊,只執行單個 HTTP 客戶端呼叫或單個 JDBC 查詢。
儘管虛擬執行緒支援執行緒區域性變數,但您應該仔細考慮使用它們,因為單個 JVM 可能支援數百萬個虛擬執行緒。
虛擬執行緒適合執行大部分時間處於阻塞狀態、通常等待 I/O 操作完成的任務。但是,它們不適用於長時間執行的 CPU 密集型操作。
虛擬執行緒用法
Thread thread = Thread.ofVirtual().start(() -> System.out.println("Hello"));thread.join();
或者
try { Thread.Builder builder = Thread.ofVirtual().name("MyThread"); Runnable task = () -> { System.out.println("Running thread"); }; Thread t = builder.start(task); System.out.println("Thread t name: " + t.getName()); t.join(); } catch (InterruptedException e) { e.printStackTrace(); }
或者
public class CreateNamedThreadsWithBuilders {
public static void main(String[] args) {
try {
Thread.Builder builder =
Thread.ofVirtual().name("worker-", 0);
Runnable task = () -> {
System.out.println("Thread ID: " +
Thread.currentThread().threadId());
};
// name "worker-0"
Thread t1 = builder.start(task);
t1.join();
System.out.println(t1.getName() + " terminated");
// name "worker-1"
Thread t2 = builder.start(task);
t2.join();
System.out.println(t2.getName() + " terminated");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
或者
try (ExecutorService myExecutor = Executors.newVirtualThreadPerTaskExecutor()) { Future<?> future = myExecutor.submit(() -> System.out.println("Running thread")); future.get(); System.out.println("Task completed"); } catch (InterruptedException | ExecutionException e) { e.printStackTrace(); }
以上是Java20文件的用法,實際使用時我發現還可以這樣:
Thread.startVirtualThread(() -> {
// do something
});
平臺執行緒和虛擬執行緒對比測試
為了測試對比,我建了一個專案
初步對比,和官網描述一致,計算密集型場景差別不大,IO密集型場景有明顯改善:
虛擬執行緒100個,IO讀檔案
平臺執行緒100個,IO讀檔案
虛擬執行緒100個,Get請求百度首頁
平臺執行緒100個,Get請求百度首頁
但是由於是本地測試,且用例比較簡陋,無法完全得出準確結論。
日後大家有實際IO密集性多執行緒場景可以實際感受下。
執行緒池?忘了它吧
開發人員通常會將應用程式程式碼從基於執行緒池的傳統 ExecutorService 遷移到虛擬執行緒每任務 ExecutorService。
執行緒池和所有資源池一樣,旨在共享昂貴的資源,
但虛擬執行緒並不昂貴,而且永遠不需要將它們池化。
一個例子感受一下新特性:Record Patterns
before:
static void printSum(Object obj) { if (obj instanceof Point p) { int x = p.x(); int y = p.y(); System.out.println(x+y); }}
after:
static void printSum(Object obj) { if (obj instanceof Point(int x, int y)) { System.out.println(x+y); }}
來自 “ ITPUB部落格 ” ,連結:https://blog.itpub.net/70024922/viewspace-2999483/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Java21的虛擬執行緒Virtual Thread初體驗Java執行緒thread
- java 21 虛擬執行緒初體驗Java執行緒
- Java21虛擬執行緒:我的鎖去哪兒了?Java執行緒
- 3 分鐘理解 Java 虛擬執行緒Java執行緒
- Tomcat 配合虛擬執行緒,一種新的程式設計體驗Tomcat執行緒程式設計
- [Java基礎]虛擬執行緒Java執行緒
- 虛擬執行緒原理及效能分析執行緒
- 使用JDK16支援的Loom虛擬執行緒的代價 – WebtideJDKOOM執行緒WebIDE
- [Java虛擬機器]Java記憶體模型與執行緒Java虛擬機記憶體模型執行緒
- 使用Loom建立虛擬執行緒 - davidOOM執行緒
- Java虛擬機器08——Java記憶體模型與執行緒Java虛擬機記憶體模型執行緒
- Java虛擬機器:JVM記憶體分代策略Java虛擬機JVM記憶體
- Java 21 虛擬執行緒:使用指南(一)Java執行緒
- 聊聊JDK19特性之虛擬執行緒JDK執行緒
- Java“虛擬執行緒”被提交到JEP草案Java執行緒
- [深入理解Java虛擬機器]執行緒Java虛擬機執行緒
- 支援JDK19虛擬執行緒的web框架,之四:看原始碼,瞭解quarkus如何支援虛擬執行緒JDK執行緒Web框架原始碼
- Java 21 正式 GA,虛擬執行緒真的來了Java執行緒
- Java 21 新特性:虛擬執行緒(Virtual Threads)Java執行緒thread
- Java中CompletableFuture與虛擬執行緒比較Java執行緒
- Spring Boot虛擬執行緒與Webflux在JWT驗證和MySQL查詢上的效能比較Spring Boot執行緒WebUXJWTMySql
- 虛擬執行緒相對於Actor模型或平臺執行緒的主要優勢? - Reddit執行緒模型
- JDK21的虛擬執行緒是什麼?和平臺執行緒什麼關係?JDK執行緒
- 虛擬執行緒原理及效能分析|得物技術執行緒
- Java 21 神仙特性:虛擬執行緒使用指南(一)Java執行緒
- Java 21 官方速覽:全面擁抱虛擬執行緒Java執行緒
- Java 21 虛擬執行緒如何限流控制吞吐量Java執行緒
- 執行緒和執行緒池執行緒
- [深入理解Java虛擬機器]第十二章 Java記憶體模型與執行緒-Java與執行緒Java虛擬機記憶體模型執行緒
- 為什麼linux下多執行緒程式如此消耗虛擬記憶體Linux執行緒記憶體
- Java虛擬機器09——執行緒安全與鎖優化Java虛擬機執行緒優化
- 使用 Jetty 12 演示 Ktor 中的虛擬執行緒支援Jetty執行緒
- 虛擬執行緒一般應用在哪些場景執行緒
- 虛擬機器系列 | 執行引擎和垃圾回收虛擬機
- 剖析虛幻渲染體系(02)- 多執行緒渲染執行緒
- 實驗--多執行緒執行緒
- 模擬主執行緒等待子執行緒的過程執行緒
- [深入理解Java虛擬機器]第十三章 執行緒安全與鎖優化-執行緒安全Java虛擬機執行緒優化