前言

Spring Boot 3.x 版本最低支持的 JDK 版本为 JDK 17,也就是说如果你还想用 JDK8的话,那能用的最高 Spring Boot 版本为 2.7。

Dubbo 在官方说明中也已经将 JDK 17 作为推荐的版本了。其他的几乎你所能用到的一些开源框架或工具包都早已支持最起码 JDK 17 了。JDK 8 不知道还能坚持多久。

JDK21是 LTS(长期支持版),至此为止,目前有 JDK8、JDK11、JDK17和 JDK21这四个长期支持版了。相信用不了多久,JDK21就会取代JDK17的位置,因为 JDK21在 JDK17的基础上做了向上增强。

下载JDK21

下载地址:https://jdk.java.net/21/

打开官方 JDK21的项目页,可以在 Features 列表看到新增的功能,带 Preview 样式的是预览功能,也就是非正式功能。

image.png

新特性介绍

序列化集合接口

在JDK 21中,Sequenced Collections的引入带来了新的接口和方法来简化集合处理。此增强功能旨在解决访问Java中各种集合类型的第一个和最后一个元素需要非统一且麻烦处理场景。

Sequenced Collections引入了三个新接口:

  • SequencedCollection
  • SequencedMap
  • SequencedSet

我们常用的 ArrayListLinkedList等都实现了这个接口。可以方便的获取第一个、最后一个元素、移除第一个、最后一个元素、在头部或尾部插入元素。

之前获取第一个元素是 list.get(0),现在用 list.getFirst()就可以了。

List<String> lists = Arrays.asList("1", "3", "8");
System.out.println(lists.getFirst());

ZGC 增加分代

可能很多人对 JVM 垃圾收集器的最新款还停留在 G1上。ZGC 是在 JDK11中推出的,ZGC是低延迟垃圾收集器,几乎是全并发,停顿时间不超过10ms。

JDK21中对 ZGC 进行了功能扩展,增加了分代功能,比如 CMS 收集器区分老年代和年轻代,这样一来,可以更频繁的回收年轻代。

要使用 ZGC 以及分代功能,需要加入下面的参数。

-XX:+UseZGC -XX:+ZGenerational

Record 匹配模式

我们先声明一个 Record

record Person(String name, int age) {}

在 JDK21之前,我们要用 instanceof 判断一个对象,并取出对象的字段时,会这样做。

Person p = new Person("John", 25);
if(p instanceof Person) {
    System.out.println("Name: " + p.name);
}

现在可以这样了,直接将参数带着,然后自动解析出参数在实体中的具体值。

Person p = new Person("John", 25);
// 可以直接解构记录字段
if(p instanceof Person(String name, int age)) {
    System.out.println("Name: " + name);
}
// 或者
switch (p) {
    case Person(String n, int a) -> {
        System.out.println("Name: " + n + ", Age: " + a);
    }
}

switch 增强

可以直接根据参数类型进行匹配.

static String switchObject(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);
        default -> obj.toString();
    };
}

虚拟线程(Virtual Threads)

虚拟线程是基于协程的线程,它们与其他语言中的协程具有相似之处,但也存在一些不同之处。

虚拟线程是依附于主线程的,如果主线程销毁了,那虚拟线程也不复存在。

相同之处:

  1. 虚拟线程和协程都是轻量级的线程,它们的创建和销毁的开销都比传统的操作系统线程要小。
  2. 虚拟线程和协程都可以通过暂停和恢复来实现线程之间的切换,从而避免了线程上下文切换的开销。
  3. 虚拟线程和协程都可以使用异步和非阻塞的方式来处理任务,提高应用程序的性能和响应速度。

不同之处:

  1. 虚拟线程是在 JVM 层面实现的,而协程则是在语言层面实现的。因此,虚拟线程的实现可以与任何支持 JVM 的语言一起使用,而协程的实现则需要特定的编程语言支持。
  2. 虚拟线程是一种基于线程的协程实现,因此它们可以使用线程相关的 API,如 ThreadLocalLockSemaphore。而协程则不依赖于线程,通常需要使用特定的异步编程框架和 API。
  3. 虚拟线程的调度是由 JVM 管理的,而协程的调度是由编程语言或异步编程框架管理的。因此,虚拟线程可以更好地与其他线程进行协作,而协程则更适合处理异步任务。

虚拟线程确实可以让多线程编程变得更简单和更高效。相比于传统的操作系统线程,虚拟线程的创建和销毁的开销更小,线程上下文切换的开销也更小,因此可以大大减少多线程编程中的资源消耗和性能瓶颈。

使用虚拟线程,开发者可以像编写传统的线程代码一样编写代码,而无需担心线程的数量和调度,因为 JVM 会自动管理虚拟线程的数量和调度。此外,虚拟线程还支持传统线程相关的 API,如 ThreadLocalLockSemaphore,这使得开发者可以更轻松地迁移传统线程代码到虚拟线程。

虚拟线程的引入,使得多线程编程变得更加高效、简单和安全,使得开发者能够更加专注于业务逻辑,而不必过多地关注底层的线程管理。

Key Encapsulation Mechanism API

介绍一种用于密钥封装机制(Key Encapsulation Mechanism,简称KEM)的API,这是一种使用公钥加密来保护对称密钥的加密技术。

向量API

废弃了对Windows 32-bit x86 (x86-32)的移植,以便后续版本删除

对将代理动态加载到正在运行的 JVM 中时发出警告,后续版本将不允许动态加载agent。


jacheut
4 声望1 粉丝