JDK 21预告:虚拟线程正式发布及十多项新特性

1 前言

Java 21进入发布候选阶段,其中包括15个最终特性,包括虚拟线程、分代Z垃圾收集器和密钥封装机制API。

JDK21计划于9月19日作为Oracle标准Java实现的下一个LTS版本发布,已进入发布候选(RC)阶段。Java 21将具有15个新特性,之前提议的第16个特性实验性Shenandoah垃圾收集器已在6月被舍弃。

进入终版的15个特性涵盖从字符串模板和结构化并发预览,到虚拟线程和密钥封装机制(KEM)API等。JDK 21于7月20日进入了第二阶段渐进开发,在6月8日首次渐进开发后。发布候选阶段从8月10日开始,与第二阶段渐进开发同时进行。第二个RC定于8月24日发布。Oracle每6个月发布一次标准Java新版本,最近的JDK 20于2022年3月21日发布。

2 JDK 21的具体提案

2.1 结构化并发(预览)

通过结构化并发API简化了并发编程,将运行在不同线程中的相关任务组视为一个工作单元。这简化了错误处理和取消,提高了可靠性并增强了可观察性。

结构化并发在JDK 20和JDK 19(2022年3月、9月发布)中进行孵化;它将以预览API形式出现在JUC包。这次唯一显著的变化是StructuredTaskScope::Fork(…)方法返回一个[Subtask]而不是Future。

结构化并发的目标包括促进一种并发编程风格,可以消除取消和关闭时常见的风险,如线程泄漏和取消延迟,并提高并发代码的可观察性。

2.2 作用域值

也处于预览状态,将使线程内外能够共享不可变数据。与线程本地变量相比,它们是首选,尤其是在使用大量虚拟线程时。

线程本地变量具有设计缺陷,包括不受约束的可变性、无边界的生命周期和昂贵的继承。作用域值允许庞大程序中的组件安全地共享数据,而无需使用方法参数。该提案在JDK 20中进行了孵化。该计划的目标包括易用性、可理解性、健壮性和性能。

2.3 禁止动态加载代理

一项准备禁止动态加载代理的提议要求,在向运行中的JVM动态加载代理时发出警告。这些警告旨在为将来的版本做准备,以默认禁止动态加载代理,以提高完整性。该提案的其他目标包括重新评估:

  • 可维护性(涉及对运行代码的特殊修改)
  • 完整性(假设运行代码不会任意更改)

之间的平衡,并确保大多数不需要动态加载代理的工具不受影响。该计划还要求将动态加载代理的能力与“超能力”功能(如深度反射)保持一致。代理是一种组件,可在应用程序运行时改变应用程序代码。这些组件由2004年JDK 5中的Java平台分析架构引入,作为一种让工具(特别是分析器)检测类的方法。尽管代理是为良性检测设计的,但高级开发人员发现了一些用例,如面向切面编程可以任意方式改变应用程序行为。同样,没有什么能阻止代理改变JDK本身等代码。 JDK 5要求代理在命令行中指定,以确保应用程序所有者批准使用代理。在JDK 21中,计划要求像启动时加载代理一样,需要应用程序所有者批准动态加载代理。这一变化将Java平台进一步接近默认完整性。

2.4 密钥封装机制API

一种通过公钥密码学安全封装对称密钥的加密技术。该提案的一个目标是让应用程序能够使用:

  • RSA密钥封装机制(RSA-KEM)
  • 椭圆曲线集成加密方案(ECIES)等KEM算法
  • 及美国国家标准与技术研究院(NIST)后量子密码学标准化过程的候选算法

另一个目标是能在更高级别的协议(如传输层安全协议TLS)和密码方案(如混合公钥加密HPKE)中使用KEM。安全提供者可以用Java或本机代码实现KEM算法,并包含RFC 9180中定义的Diffie-Hellman KEM(DHKEM)的实现。

2.5 弃用Windows 32位x86端口

以便在未来版本中删除,目的是在未来的版本中删除该端口。该提案旨在更新构建系统,以便尝试为Windows 32位x86配置构建时发出错误消息。消息可以通过新的配置选项抑制。此外,该计划是将端口及相关的端口特定功能标记为已弃用以删除相关文档。该提案指出,支持32位操作的最后一个Windows操作系统Windows 10将于2025年10月结束生命周期。

2.6 无名类和实例main方法预览

旨在使Java语言进化,以便学生在无需理解面向大型程序设计的语言特性的情况下编写第一个Java程序。学生可以为单类程序编写简化的声明,然后无缝地扩展程序以使用更高级的特性,而不是使用Java的单独方言。该提案不仅可以为Java提供平稳的入门,而且可以减少编写简单Java程序(如脚本和命令行实用程序)的麻烦。

2.7 无名模式和变量的预览

未命名模式匹配记录组件,而不声明组件的名称或类型,未命名变量可以初始化但不使用。两者都用下划线字符_表示。该提案旨在通过省略不必要的嵌套模式来改善记录模式的可读性,并通过识别必须声明但不会使用的变量来改善所有代码的可维护性。

2.8 分代ZGC

旨在通过为年轻对象和旧对象维护独立的代来改善应用程序性能。年轻对象往往很快就会死亡;维护独立的代将允许ZGC更频繁地收集年轻对象。运行在分代ZGC上的应用程序应会看到以下好处:分配中断风险更低,需要的堆内存开销更低,垃圾收集CPU开销更低。这些好处应该可以在吞吐量不明显下降的情况下实现。

2.9 记录模式

在JDK 19和JDK 20中进行了预览,用于解构记录值。记录模式和类型模式可以嵌套,以启用强大的、声明性的和可组合的数据导航和处理形式。该提案的目标包括扩展模式匹配以解构记录类的实例,添加嵌套模式以启用更可组合的数据查询。此特性与switch表达式和语句的模式匹配(见下文)共同演化。当前的JEP将在继续的经验和反馈的基础上通过进一步完善来最终确定该特性。除了少量编辑变化外,主要变化是删除了记录模式在增强的for语句标题中出现的支持。该特性可能会在未来的JEP中重新提出。

2.10 switch的模式匹配

使得switch表达式或语句可以针对许多模式进行测试,每个模式都有特定的操作,这样复杂的数据查询可以安全简洁地表达。该特性最初在JDK 17中提出,之后在JDK 18、JDK 19和JDK 20中进行了完善。它将在JDK 21中通过进一步的优化最终确定。与前面的JEP相比,主要变化是删除了带括号的模式并允许合格的enum常量,如带switch表达式和语句的常量。目标包括通过允许模式出现在case标签中来扩展switch表达式和语句的表达能力和适用范围,允许switch的历史 null敌意在需要时得到放松,并通过要求模式switch语句覆盖所有潜在的输入值来增加switch语句的安全性。另一个目标是确保现有的switch表达式和语句继续编译而不变,并具有相同的语义。

2.11 向量API的第六个孵化器

该API表达了在支持的CPU体系结构上可靠编译为优化向量指令的向量计算,其性能优于等效的标量计算。向量API此前在JDK 16至JDK 20中进行了孵化。这个最新版本包括性能增强和错误修复。该提案的目标包括清晰简洁,与平台无关,并在x64和AArch64体系结构上提供可靠的运行时编译和性能。其他目标包括在向量计算无法完全表示为向量指令序列时优雅降级。

2.12 外部函数和内存API的第三次预览

它使Java程序能够与Java运行时之外的代码和数据进行互操作。通过高效调用外部函数和安全访问外部内存,该API使Java程序能够调用本机库并处理本机数据,而无需使用JNI(Java本机接口)的脆弱性和危险性。该API此前在JDK 20和JDK 19中进行了预览。 JDK 21预览中的改进包括带有新的元素来解引用地址布局的增强布局路径、Arena接口中的本地段生命周期的集中管理、备用本机链接器实现以及VaList的删除。该提案的目标包括易用性、性能、通用性和安全性。它的目标不是在此API之上重新实现JNI,也不是以任何方式更改JNI。

2.13 虚拟线程

是轻量级线程,它承诺大大减少编写、维护和观察高吞吐量并发应用程序的工作量。该计划的目标包括使按线程请求风格编写的服务器应用程序能够在接近最佳硬件利用率的情况下扩展,使使用lang.Thread API的现有代码通过最小更改采用虚拟线程,并使用当前JDK工具轻松调试和分析虚拟线程。虚拟线程在JDK 20和JDK 19中进行了预览,将在JDK 21中最终确定。在JDK 21中,虚拟线程现在始终支持线程本地变量,并使创建不具有这些变量的虚拟线程成为不可能。保证对线程本地变量的支持可以确保更多现有库可以不变地与虚拟线程一起使用,并帮助将面向任务的代码迁移到使用虚拟线程。

2.14 序列集合

提案引入了表示具有定义遭遇顺序的集合的接口。每个集合都有明确定义的第一个和第二个元素等,直到最后一个元素。提供了统一的API来接受第一个和最后一个元素并以相反顺序处理元素。该提案的动机是Java的集合框架缺少表示具有定义遭遇顺序的元素序列的集合类型。它还缺少适用于这些集合的统一操作集。这些缺陷一直是个问题和抱怨的来源。该提案要求为序列集合、集合和映射定义接口,并将这些接口 retrofit 到现有的集合类型层次结构中。所有这些新方法都有默认实现。

2.15 字符串模板

JDK 21中的预览功能,它通过将字面文本与嵌入式表达式和处理器结合来补充Java的现有字符串文本块,以产生特定结果。这种语言特性和API旨在通过使动态计算的值易于表示字符串来简化Java程序的编写。它有望增强表达式的可读性,提高程序安全性,保持灵活性,并简化使用以非Java语言编写的字符串的API。启用从字面文本和嵌入式表达式组合派生非字符串表达式的开发也是一个目标。

与这些JDK增强提案分开,据Oracle的Java团队称,JDK 21将更改JDK在Windows上为网络接口分配名称的方式。执行网络多播或使用java.net.NetworkInterface API的应用程序维护人员应注意此更改。

JDK历史上为Windows上的网络接口合成名称。这已更改为使用Windows操作系统分配的名称。此更改可能会影响使用NetworkInterface.GetbyName(String name)方法查找网络接口的代码。JDK 21还将在JDK飞行记录器中进行关键更改,包括使从命令行分析飞行记录更加容易。

作为LTS版本,JDK 21将获得5年首要支持和直到2031年9月的延长支持。当前的LTS版本是在2021年9月发布的JDK 17。非LTS版本(如JDK 20和JDK 19)仅获得6个月的首要支持,没有延长支持。LTS版本每两年发布一次。

参考

  • https://openjdk.org/projects/jdk/21/

参考

猜你喜欢

转载自blog.csdn.net/qq_33589510/article/details/132427641