JDK21來了!附重要更新說明

来源:https://www.cnblogs.com/dafanjoy/archive/2023/09/18/17709944.html
-Advertisement-
Play Games

JDK21 計劃23年9月19日正式發佈,雖然一直以來都是“版本隨便出,換 8 算我輸”,但這麼多年這麼多版本的折騰,如果說之前的 LTS版本JDK17你還覺得不香,那 JDK21還是有必要關註一下,因為會有一批重要更新發佈到生產環境中,特別是千呼萬喚的虛擬線程,雖然說這東西我感覺不需要的用不到,需 ...


JDK21 計劃23年9月19日正式發佈,雖然一直以來都是“版本隨便出,換 8 算我輸”,但這麼多年這麼多版本的折騰,如果說之前的 LTS版本JDK17你還覺得不香,那 JDK21還是有必要關註一下,因為會有一批重要更新發佈到生產環境中,特別是千呼萬喚的虛擬線程,雖然說這東西我感覺不需要的用不到,需要的早都轉go了,哈哈,但作為近幾年JDK一個“重大”的更新,在實際開發應用中還是是有很大價值的。所以這篇文章主要提取了這次更新中個人感覺比較有價值的幾點做個基本的介紹,想要嘗鮮的同學可以看下。

Visual Threads (虛擬線程) -JEP 444

先看下官方對虛擬線程(Visual Threads)描述:

Today, every instance of java.lang.Thread in the JDK is a platform thread. A platform thread runs Java code on an underlying OS thread and captures the OS thread for the code's entire lifetime. The number of platform threads is limited to the number of OS threads.

virtual thread is an instance of java.lang.Thread that runs Java code on an underlying OS thread but does not capture the OS thread for the code's entire lifetime. This means that many virtual threads can run their Java code on the same OS thread, effectively sharing it. While a platform thread monopolizes a precious OS thread, a virtual thread does not. The number of virtual threads can be much larger than the number of OS threads.

Virtual threads are a lightweight implementation of threads that is provided by the JDK rather than the OS. They are a form of user-mode threads, which have been successful in other multithreaded languages (e.g., goroutines in Go and processes in Erlang). User-mode threads even featured as so-called "green threads" in early versions of Java, when OS threads were not yet mature and widespread. However, Java's green threads all shared one OS thread (M:1 scheduling) and were eventually outperformed by platform threads, implemented as wrappers for OS threads (1:1 scheduling). Virtual threads employ M:N scheduling, where a large number (M) of virtual threads is scheduled to run on a smaller number (N) of OS threads.

總結下就是之前java中的線程是“platform thread”即平臺線程,它由操作系統線程為基礎,按照1:1的模式調度,這導致線程的創建與執行都是很耗資源的,同時數量也受系統的約束;但新的虛擬線程則是由JDK提供,你可以把它看作是在平臺線程基礎上創建的“一批”線程,它們有效地共用所屬的平臺線程也就是操作系統線程的資源,從而提升系統利用率,並不受數量限制。

目標描述:

1、Enable server applications written in the simple thread-per-request style to scale with near-optimal hardware utilization.

可以每個請求開啟一個虛擬線程,實現簡單直接的同時可以最大程度的提升硬體利用率;

2、Enable existing code that uses the java.lang.Thread API to adopt virtual threads with minimal change.

之前的多線程實現代碼可以在較小的改動下完成向虛擬線程的遷移;

3、Enable easy troubleshooting, debugging, and profiling of virtual threads with existing JDK tools.

使用現有JDK工具可以完成虛擬線程的代碼調試、分析與問題定位;

說白了就是現在我們不用怎麼改代碼就可以創建一個輕量級的虛擬線程,實現簡單同時還能夠充分發揮硬體性能。

一個簡單的代碼示例

try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
    IntStream.range(0, 10000).forEach(i -> {
        executor.submit(() -> {
            Thread.sleep(Duration.ofSeconds(1));
            return i;
        });
    });
}  // executor.close() is called implicitly, and waits

SequencedCollection Interface(順序集合 介面)

兄弟們,作為一個天天CRUD,CPU跑不滿20%的程式員, 相比上面的虛擬線程,這次關於集合類介面的更新我感覺更實在一些

JDK21中我們常用的Set、List、Deque與Map集合類分別繼承實現了SequencedCollection、 SequencedMap 介面,為我們執行一些順序性操作比如獲取頭尾值提供了各類介面方法

繼承關係如下圖所示:

介面定義如下

interface SequencedCollection<E> extends Collection<E> {
    // new method
    SequencedCollection<E> reversed();
    // methods promoted from Deque
    void addFirst(E);
    void addLast(E);
    E getFirst();
    E getLast();
    E removeFirst();
    E removeLast();
}
interface SequencedSet<E> extends Set<E>, SequencedCollection<E> {
    SequencedSet<E> reversed();    // covariant override
}
interface SequencedMap<K,V> extends Map<K,V> {
    // new methods
    SequencedMap<K,V> reversed();
    SequencedSet<K> sequencedKeySet();
    SequencedCollection<V> sequencedValues();
    SequencedSet<Entry<K,V>> sequencedEntrySet();
    V putFirst(K, V);
    V putLast(K, V);
    // methods promoted from NavigableMap
    Entry<K, V> firstEntry();
    Entry<K, V> lastEntry();
    Entry<K, V> pollFirstEntry();
    Entry<K, V> pollLastEntry();
}

Record Patterns (記錄模式)-JEP 440

這個更新主要簡化了類型判斷與賦值的使用,類型判斷後無需顯式強制轉換且如果模式匹配,變數被初始化為要匹配的模板值, 這個說起來比較拗口,結合代碼大家理解下,我感覺還是挺有用的,這裡我把JDK8 JDK17 JDK21 的實現進行一個對比,大家就明白了。

// As of Java 8
record Point(int x, int y) {}

static void printSum(Object obj) {
    if (obj instanceof Point) {
        Point p = (Point) obj;
        int x = p.x();
        int y = p.y();
        System.out.println(x+y);
    }
}
// As of Java 16
record Point(int x, int y) {}

static void printSum(Object obj) {
    if (obj instanceof Point p) {
        int x = p.x();
        int y = p.y();
        System.out.println(x+y);
    }
}
// As of Java 21
static void printSum(Object obj) {
    if (obj instanceof Point(int x, int y)) {
        System.out.println(x+y);
    }
}

Pattern Matching for switch (switch模式匹配) – JEP 441

switch 的模式匹配可以與Record Patterns結合使用 允許在任何對象上制定 switch 語句和表達式。看一下代碼例子:

static String formatterPatternSwitch(Object obj) {
    return switch (obj) {
        case Integer i -> String.format("int %d", i);
        case Long l    -> String.format("long %d", l);
        case Double d  -> String.format("double %f", d);
        case String s  -> String.format("String %s", s);
        case Position(int x, int y)   -> String.format("String %s,String %s", x,y);
        default        -> obj.toString();
    };
}

同時當編譯器判斷所有分支都已涵蓋時,switch不再需要分支default,如下麵的代碼

void flyJava21(Direction direction) { 
    switch (direction) {
       case CompassDirection.NORTH -> System.out.println("Flying north"); 
       case CompassDirection.SOUTH -> System.out.println("Flying south");
       case CompassDirection.EAST -> System.out.println("Flying east");
       case CompassDirection.WEST -> System.out.println("Flying west"); 
       case VerticalDirection.UP -> System.out.println("Gaining altitude"); 
       case VerticalDirection.DOWN -> System.out.println("Losing altitude"); 
    } 
}

Generational ZGC(分代式 ZGC) -JEP 439

主要是增加了對分代的支持,提高垃圾回收的性能,看下整體描述

To ensure a smooth succession, we will initially make Generational ZGC available alongside non-generational ZGC. The -XX:+UseZGC command-line option will select non-generational ZGC; to select Generational ZGC, add the -XX:+ZGenerational option:

使用命令行選項 -XX:+UseZGC 將選擇非分代式 ZGC;要選擇分代式 ZGC,需要添加 -XX:+ZGenerational 選項。

$ java -XX:+UseZGC -XX:+ZGenerational ...

In a future release we intend to make Generational ZGC the default, at which point -XX:-ZGenerational will select non-generational ZGC. In an even later release we intend to remove non-generational ZGC, at which point the ZGenerational option will become obsolete.

總結就是當前版本中如果想使用ZGC,命令行選項增加 -XX:+UseZGC,但預設是非分代式GC;要使用分代式ZGC ,需要改為 $ java -XX:+UseZGC -XX:+ZGenerational ,而在後續的版本中會預設改為分代GC。

以上就是JDK21版本中我感覺一些有價值的更新,如果大家希望能夠更進一步的瞭解還是要去官網https://openjdk.org/projects/jdk/21/ 自行查看,併在發佈之後在使用中實際驗證。

之所以有這次總結,主要還是有感於java近年來受到其他各類語言的衝擊,頗有垂垂老矣的感覺,讓我這個C#出身的javaer又想起了一段不好的回憶,哈哈,所以看看這次的更新是否能給點力, 當前java語言的下行趨勢也可以說是國內IT行業興衰起伏的一個側面寫照,當然作為一個提供生產力的編程語言,圍繞java建立起的整個完整、穩定、強大的生態仍然會在它適合的領域起到重要的作用,這是一時半會無法改變的,但你指望靠它乾到退休估計連收了學費的培訓機構也不敢這樣說,程式員的職業壽命從來不是某種編程語言決定的。最後我還是想說入行的菜鳥才糾結於語言優劣,成熟老手知道這早有定論,讓我們大聲喊出:   

                                     "PHP是最好的語言"

這不是玩梗,因為從某種角度上講: 

                                 "生產力才是決定語言生死的關鍵"
  •  
  •  
  •  參考資料:https://openjdk.org/projects/jdk/21/
  •  
  •  

   關註微信公眾號,查看更多技術文章。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 變數 變數是用於存儲數據值的容器。 創建變數 Python沒有用於聲明變數的命令。 變數在您第一次為其分配值時被創建。 示例 x = 5 y = "John" print(x) print(y) 變數不需要聲明為特定類型,並且甚至在設置後可以更改類型。 示例 x = 4 # x的類型為int x = ...
  • 0 前言 一般初學者學習編碼和[錯誤處理]時,先知道[編程語言]有一種處理錯誤的形式或約定(如Java就拋異常),然後就開始用這些工具。但卻忽視這問題本質:處理錯誤是為了寫正確程式。可是 1 啥叫“正確”? 由解決的問題決定的。問題不同,解決方案不同。 如一個web介面接受用戶請求,參數age,也許 ...
  • 什麼是裝飾器,它們如何被使用,以及我們如何利用它們來構建代碼。我們將看到裝飾器是如何成為一個強大的工具,可以用來為我們的應用程式添加功能,並且可以在Python編程語言中找到。 裝飾器順序 在Python中,裝飾器是一個特殊的函數,可以修改另一個函數的行為。裝飾器是一種設計模式,它在不改變現有對象結 ...
  • dataclass 到 Python 中的 JSON JavaScript Object Notation或JSON表示使用編程語言中的文本組成的腳本(可執行)文件來存儲和傳輸數據。 Python通過JSON內置模塊支持JSON。因此,我們在Python腳本中導入JSON包,以利用這一能力。 JSO ...
  • 前言 很多時候,由於種種不可描述的原因,我們需要針對單個介面實現介面限流,防止訪問次數過於頻繁。這裡就用 redis+aop 實現一個限流介面註解 @RedisLimit 代碼 點擊查看RedisLimit註解代碼 import java.lang.annotation.*; /** * 功能:分佈 ...
  • 對重寫代碼說不。 以下為譯文: 1、重寫代碼消耗了12個月! 我們從頭開始重寫代碼浪費的時間。 你能想象在軟體行業,12個月的時間沒有任何新產品推出,沒有任何新版本更新嗎? 真的,我不由自主地問自己這個問題: 在這個快速發展的世界里,12月的時間能讓我們做多少事情? “2015年1月20日,星期二, ...
  • Nacos 2.x版本增加了GRPC服務介面和客戶端,極大的提升了Nacos的性能,本文將簡單介紹grpc-java的使用方式以及Nacos中集成GRPC的方式。 grpc-java GRPC是google開源的、以protobuf作為序列化方式、以http2作為通信協議的高性能rpc框架。 grp ...
  • 1.什麼是權重比例 權重比例計算即將各數值乘以相應的權數,然後加總求和得到總體值,再除以總的單位數。 如何計算 有一個對象集合為[A,B,C,D,E,F,G,H,I,J],其對象的全紅 總權重為10 每一個對象的權重為1/10=0.1 2.什麼是權重覆蓋區域 權重覆蓋區域是對象在整體權重範圍中的鎖分 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...