JDK 21开发者新特性详解:虚拟线程、结构化并发与记录模式

JDK 21引入了多项重要特性,包括虚拟线程提升并发性能、结构化并发简化多线程编程、记录模式优化数据导航,以及字符串模板增强安全性。这些更新显著改善了Java开发体验和代码效率。

JDK 21开发者新特性

2023年9月19日,JDK 21正式发布,为Java生态系统带来多项新功能,包括虚拟线程、记录模式和顺序集合等。此外,JDK 21还包含一些预览特性,如字符串模板、作用域值和结构化并发。本文重点介绍此版本中的六项新功能。

虚拟线程

Java的传统线程模型在创建超过操作系统处理能力的线程时,会迅速成为昂贵的操作。此外,在线程生命周期较短的情况下,创建线程的成本也很高。

虚拟线程通过将Java线程映射到管理线程操作的载体线程(即挂载/卸载)来解决此问题。相比之下,载体线程与操作系统线程协作。这种抽象为开发者提供了更大的灵活性和控制力。参见图1。

图1:JDK 21中的虚拟线程模型。

以下是虚拟线程的示例,与操作系统/平台线程形成鲜明对比。该程序使用ExecutorService创建10,000个任务,并等待所有任务完成。在幕后,JDK将在有限数量的载体线程和操作系统线程上运行此程序,使您能够轻松编写并发代码。

1
2
3
4
5
6
7
8
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
    IntStream.range(0, 10_000).forEach(i -> {
        executor.submit(() -> {
            Thread.sleep(Duration.ofSeconds(1));
            return i;
        });
    });
}  // executor.close()隐式调用,并等待

结构化并发(预览)

结构化并发与虚拟线程紧密相关,旨在通过提供增强开发者体验的API来消除取消、关闭、线程泄漏等常见风险。如果任务拆分为并发子任务,它们都应返回到同一位置,即任务的代码块。

在图2中,findUser和fetchOrder都需要执行以从不同服务获取数据,然后使用该数据组合结果,并在响应中返回给消费者。通常,这些任务可以并发执行,但如果findUser未返回,则容易出错;fetchOrder需要等待其完成,最后执行Join操作。

图2:结构化并发示例。

此外,子任务的生命周期不应超过父任务本身。想象一个任务操作,如果每个操作都在线程中执行,它将并发组合多个快速运行的I/O操作的结果。结构化并发模型通过利用虚拟线程API和StructuredTaskScope,使线程编程更接近单线程代码风格的简便性。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
Response handle() throws ExecutionException, InterruptedException {
    try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {
        Supplier<String>  user  = scope.fork(() -> findUser());
        Supplier<Integer> order = scope.fork(() -> fetchOrder());

        scope.join()            // 加入两个子任务
             .throwIfFailed();  // ...并传播错误

        // 此处,两个子任务均已成功,因此组合它们的结果
        return new Response(user.get(), order.get());
    }
}

顺序集合

在JDK 21中,引入了一组新的集合接口,以增强使用集合的体验(图3)。例如,如果需要从集合中获取元素的逆序,根据所使用的集合,可能会很繁琐。根据所使用的集合,检索遇到顺序可能存在不一致;例如,SortedSet实现了一个,但HashSet没有,这使得在不同数据集上实现此功能变得繁琐。

图3:顺序集合。

为了解决此问题,SequencedCollection接口通过添加reverse方法以及获取第一个和最后一个元素的能力来辅助遇到顺序。此外,还有SequencedMap和SequencedSet接口。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
interface SequencedCollection<E> extends Collection<E> {
    // 新方法
    SequencedCollection<E> reversed();
    // 从Deque提升的方法
    void addFirst(E);
    void addLast(E);
    E getFirst();
    E getLast();
    E removeFirst();
    E removeLast();
}

因此,现在不仅可以获取遇到顺序,还可以删除和添加第一个和最后一个元素。

记录模式

记录在Java 14中作为预览引入,这也为我们提供了Java枚举。record是Java中的另一种特殊类型,其目的是简化仅作为数据载体的类的开发过程。

在JDK 21中,记录模式和类型模式可以嵌套,以实现声明式和可组合的数据导航和处理。

1
2
3
4
5
// 创建记录:
Public record Todo(String title, boolean completed){}

// 创建对象:
Todo t = new Todo(Learn Java 21, false);

在JDK 21之前,需要解构整个记录以检索访问器。然而,现在获取值要简化得多。例如:

1
2
3
4
5
6
static void printTodo(Object obj) {
    if (obj instanceof Todo(String title, boolean completed)) {
        System.out.print(title);
        System.out.print(completed);
    }
}

记录模式的另一个优势是嵌套记录和访问它们。JEP定义本身的一个示例显示了获取Point值的能力,这些值是ColoredPoint的一部分,而ColoredPoint嵌套在Rectangle中。这比以前每次都需要解构所有记录时更有用。

字符串模板

字符串模板是JDK 21中的预览特性。然而,它试图为字符串操作带来更高的可靠性和更好的体验,以避免有时可能导致不良结果(如注入)的常见陷阱。现在,您可以编写模板表达式并在字符串中呈现它们。

1
2
3
4
// 从Java 21开始
String name = "Shaaf"
String greeting = "Hello \{name}";
System.out.println(greeting);

在这种情况下,第二行是表达式,调用时应呈现Hello Shaaf。此外,在可能存在非法字符串的情况下,例如可能导致安全问题的SQL语句或HTML,模板规则只允许转义引号,并且HTML文档中不允许非法实体。

JDK 21中的更多JEP

本文未涵盖但在另一篇文章中讨论的其他JEP包括:

  • JEP 439:分代ZGC
  • JEP 441:switch模式匹配
  • JEP 442:外部函数和内存API(第三次预览)
  • JEP 443:未命名模式和变量(预览)
  • JEP 445:未命名类和实例主方法(预览)
  • JEP 448:向量API(第六次孵化)
  • JEP 449:弃用Windows 32位x86端口以移除
  • JEP 451:准备禁止动态加载代理
  • JEP 452:密钥封装机制API

获取Java支持

红帽客户通过订阅红帽运行时、红帽企业Linux和红帽OpenShift,可以获得对OpenJDK和Eclipse Temurin的支持。请联系您当地的红帽代表或红帽销售以获取更多详细信息。您可以根据红帽产品更新和支持生命周期获得对Java和其他运行时的支持。

资源

  • 视频:什么是Eclipse Temurin?
  • 开始使用Eclipse Temurin
  • 红帽加入Eclipse Adoptium工作组
  • Eclipse Adoptium实现其第一个Java SE版本
  • 红帽在Microsoft Windows上引入对OpenJDK的商业支持
  • OpenJDK的历史和未来

← 上一篇 下一篇 →

目录

  • 虚拟线程
  • 结构化并发(预览)
  • 顺序集合
  • 记录模式
  • 字符串模板
  • JDK 21中的更多JEP
  • 获取Java支持
  • 资源

特色标签 administrator, ant, automation, build, cache, ci, command, computers, continous, design, design-patterns, docker, engineering, fedora, gof, how-to, howto, ibm, infinispan, integration, jacl, java, jdbc, jdk-21, jython, kubernetes, llm, migration, mq, openjdk, openshift, patterns, programming, quarkus, redhat, release, rhel, scm, scripting, singleton, singleton-pattern, software, software-development, svn, sysadmin, tips, tools, utils, websphere, wsadmin

版权所有 © Shaaf’s blog 2025

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计