你好呀,我是歪歪。
朋友們,好訊息,好訊息,重磅好訊息。
從今年年初就一直在喊的具有革命性、未來性、開創新紀元的 JDK 21 按照官方的時間計劃表,今天終於是要正式 GA 了:
https://openjdk.org/projects/jdk/21/
GA,就是我上面框起來的“General Availability”的縮寫,直譯成中文,雖然是“普通可用”的意思,但是在軟體行業,它就代表正式版。
如果對外釋出一個 GA 版本,就意味著這個版本已經經過全面的測試,不存在任何重大的 bug,可供普通使用者進行使用。
既然說到 GA 了,歪師傅也順便給大家普及一下一般我們看到的版本號的含義。
比如我們經常會看到一些軟體釋出的時候都會帶上 Alpha、Beta、Gamma、RC 等等這些莫名其妙的單詞,它們代表什麼意思呢?
- Alpha:軟體或系統的內部測試版本,僅內部人員使用。一般不向外部發布,通常會有很多 Bug,除非你也是測試人員,否則不建議使用,alpha 就是 α,是希臘字母的第一位,表示最初級的版本,beta 就是 β,alpha 版就是比 beta 還早的測試版,一般都是內部測試的版本。
- Beta:公開測試版。β 是希臘字母的第二個,顧名思義,這一版本通常是在 Alpha 版本後,該版本相對於 Alpha 版已有了很大的改進,消除了嚴重的錯誤,但還是存在著一缺陷,需要經過多次測試來進一步消除。這個階段的版本會一直加入新的功能。
- Gamma:
軟體或系統接近於成熟的版本,只需要做一些小的改進就能發行。是 beta 版做過一些修改,成為正式釋出的候選版本。 - RC:Release Candidate,發行候選版本。和 Beta 版最大的差別在於 Beta 階段會一直加入新的功能,但是到了 RC 版本,幾乎就不會加入新的功能了,而主要著重於除錯。RC 版本是最終發放給使用者的最接近正式版的版本,發行後改正 bug 就是正式版了,就是正式版之前的最後一個測試版。
- GA:General Available,正式釋出的版本,這個版本就是正式的版本。在國外都是用 GA 來說明 release 版本的。比如:MySQL Community Server 5.7.21 GA 這是 MySQL Community Server 5.7 第 21 個發行穩定的版本,GA 意味著 General Available,也就是官方開始推薦廣泛使用了。
- Release:這個版本通常就是所謂的“最終版本”,在前面版本的一系列測試版之後,終歸會有一個正式版本,是最終交付使用者使用的一個版本,該版本有時也稱為標準版。一般情況下,Release 不會以單詞形式出現在軟體封面上,取而代之的是符號(R)。
- Stable:穩定版。在開源軟體中,都有 stable 版,這個就是開源軟體的最終發行版,使用者可以放心大膽的用了。這一版本基於 Beta 版,已知 Bug 都被修復,一般情況下,更新比較慢。
除了上面的這些之外,我們還經常看見一個 LTS 的版本號。
LTS,Long Term Support,長期支援版,是指標對軟體的某一版本,提供長時間的技術支援、安全更新和錯誤修復。
相對於非 LTS 版本,LTS 版本被認為是更為穩定、可靠和安全的版本。因此,在需要穩定性和安全性較高的場景中,如生產環境、企業級應用等,LTS 版本得到廣泛的應用。
在 Java 領域,LTS 版本是指 Oracle 公司釋出的 Java SE(Standard Edition,標準版)中,每隔一段時間釋出一個長期支援版本。
自 2018 年開始,Oracle Java SE 8 、Java SE 11、Java SE 17 成為了 LTS 版本,分別提供了 3 年、 8 年、至少 3 年的支援。
你看,一個小小的 GA 裡面,隱藏了這麼多的小知識點,讓歪師傅一不小心就鋪(水)墊(了)這麼長。
說會到 JDK 21 今天的 GA 版本,一共釋出了 15 個新特性:
一眼望去,其中最扎眼的,也是描述最短的一個 Feature 是 444 號 Virtual Threads:
https://openjdk.org/jeps/444
可以說這個特性就是 JDK 21 這個版本中最受矚目、最值得期待的一個特性了。
Virtual Threads,就是虛擬執行緒,從 JDK 19 吆喝到 JDK 20,終於在 JDK 21 現真身了。
前面我形容 JDK 21 的時候提到了一個詞:開創新紀元。
值得就是它,根據官方介紹,虛擬執行緒的出現,確實是開啟了併發程式設計的新紀元,輕量且高效,用更少的開銷,處理更多的任務。
最重要的是看看這個:
來,翻譯翻譯,什麼叫做“minimal change”?
minimal,就是小小的也很可愛,就是“極小的”。
change,就是變化。
官方表示,使用 java.lang.Thread API 的現有程式碼,只需做 極少改動(minimal change)即可啟用虛擬執行緒。
少到你升級到 JDK 21 之後,只需要把建立執行緒池的地方修改為這樣就能啟用虛擬執行緒:
至於這個玩意到底有多牛逼,你可以隨便在網上檢索一下,已經有很多相關的文章了。
但是我還是建議你直接看官方的這個描述,這才是第一手資料出現的地方,如果讓我來描述,我也只能是對於官方文章進行拙劣的翻譯。
https://openjdk.org/jeps/444
除了 444 之外,也有其他的很多實用的特性。
根據官方的資訊,它們把這 15 個新特性按照 JEP 的形式分為四類:核心 Java 庫,Java 語言規範,HotSpot 和安全庫。
https://www.infoq.com/news/2023/09/java-21-so-far/
納入核心 Java 庫的 6 個新特性分別是:
- JEP 431:序列集合
- JEP 442:外部函式和記憶體 API(第三次預覽)
- JEP 444:虛擬執行緒
- JEP 446:作用域值(預覽)
- JEP 448:Vector API (第六次孵化器)
- JEP 453:結構化併發(預覽)
納入 Java 語言規範的 5 個新特性分別是:
- JEP 430:字串模板(預覽)
- JEP 440:記錄模式
- JEP 441:switch 模式匹配
- JEP 443:未命名模式和變數(預覽)
- JEP 445:未命名類和例項主方法(預覽)
納入 HotSpot 的 3 個新特性分別是:
- JEP 439:分代 ZGC
- JEP 449:棄用 Windows 32 位 x86 移植
- JEP 451:準備禁止動態載入代理
納入安全庫的 1 個新特性是:
- JEP 452:金鑰封裝機制 API
其中 445 號提案,也小小的火了一把,因為它被大多數網友調侃為“卵用不大”。
因為這個提案是為了簡化 Hello World 的寫法。
https://openjdk.org/jeps/445
在這個提案中,作者認為我們的 Hello World 太複雜了,要寫這麼多程式碼:
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}
所以他提議,為了 students 和 beginner 更快更好的入門 Java,應該簡化成這樣,
但是這個提案也強調了:這是預覽語言功能,預設禁用。
如果你要用,需要這樣操作:
- 用 javac --release 21 --enable-preview Main.java 編譯程式,用 java --enable-preview Main 執行程式。
- 或者,當使用原始碼啟動器 source code launcher,時,用 java --source 21 --enable-preview Main.java 執行程式。
對於這個功能,怎麼說的?
我的評價是:這很難評。
最後,再說一下編號為 439 的提案。
https://openjdk.org/jeps/439
ZGC,大家不陌生了吧?
這個提案提到它是幹啥呢?
目前的版本中,ZGC 都是不分代 GC 的。在 JDK 21 的版本中,提供了分代 GC 的功能,但是預設是關閉狀態,需要透過配置開啟:
而且,注意最後這句話:
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.
在未來的版本中,官方會把 ZGenerational 設為預設值,即預設開啟 ZGC 的分代 GC。
在更晚的版本中,官方會考慮刪除 ZGC 的不分代 GC 功能,到時候 ZGenerational 這個配置就會被一併“最佳化”。
說到這個 ZGC 的分代 GC,我突然想起了一個有意思的問題。
就是 2018 年,在 JDK 11 的裡面,剛剛開始宣傳 ZGC 的時候,就有人問:ZGC 為什麼不進行分代啊?
關於這個問題,我在 R 大那裡看到了一個權威的回答:
https://www.zhihu.com/question/287945354/answer/458761494
沒有什麼特別的原因,就是“因為分代實現起來麻煩,想先實現出比較簡單可用的版本”而已。
這句話,像不像我們常常聽到的:先跑起來再說?
但是人家的“跑起來再說”和我們的“跑起來再說”完全不是一個維度的東西。
至少,人家提供的“跑起來”的版本,從 2018 年跑到了 2023 年,5 年時間。
而你的“跑起來再說”可能一週後就接到了全新的、不相容的需求。
5 年就更別想了,業務可能都被砍了,跑不起來了。(手動狗頭)
既然都提到了 ZGC 了,那就順便提一嘴 Shenandoah 吧。
根據官方的訊息,最開始 JDK 21 的版本中是包含了 Shenandoah 的。
https://openjdk.org/jeps/404
但是為什麼 GA 版本中沒有看到它的影子呢?
可以看看官方 6 月份的這個郵件:
https://mail.openjdk.org/pipermail/jdk-dev/2023-June/007959.html
別問,問就是時間緊,任務重,申請延期。
首先描述了原因:
Given the risks identified during the review process and the lack of time available to perform the thorough review that such a large contribution of code requires
因為 Shenandoah 在審查的過程中發現了明確的風險,並且沒有足夠的時間來進行針對大量程式碼改動所需的評審。
然後畫了一個新餅:
take the time to deliver the best Generational Shenandoah that we can.
Shenandoah 團隊決定“盡他們所能提供最好的分代 Shenandoah”。
並給自己設定了一個新任務,將 JDK 22 作為釋出目標:
We will seek to target JDK 22.
能怎麼辦,等著唄。
反正你發任你發,我用 Java 8!
話雖然是這麼說,但是我還是希望在我短暫的職業生涯中,有幸能在生產上使用到 JDK 21,體會一下虛擬執行緒和 ZGC 帶來的雙重服務。