Java 19 正式发布,改善多线程、并发编程难度-LMLPHP

Java 19 在数分钟前正式发布,这是一个非 LTS(长期支持)版本。该版本的七项功能包括结构化并发、记录模式、外部函数和内存 API 的预览,以及对开源 Linux/RISC-V 指令集架构 (ISA) 的支持。

新特性

  • JEP 405 Record Patterns (预览)

  • JEP 422 Linux/RISC-V Port

  • JEP 424 Foreign Function & Memory API (预览)

  • JEP 425 Virtual Threads (预览)

  • JEP 426 Vector API (第四次孵化)

  • JEP 427 Pattern Matching for switch (第三次预览)

  • JEP 428 Structured Concurrency (孵化)

JEP 405 Record Patterns

这是对Java 17正式生效的Record Class的增强。JEP 405让记录模式和类型模式可以嵌套,以实现强大的、可声明的、可组合的数据处理形式。

在JDK 16 中,我们已经可以实现下列特性:

// jdk 16 以前
if (o instanceof String) {
    // 及时类型匹配 依然需要转换
    String s = (String)o;     
}

// jdk 16 以后
if (o instanceof String s) {
    // 直接使用 s 
}

但是上面的特性应用在Record Class中并不是很丝滑,依然需要通过属性方法来获取属性值:

public record Position(int x, int y) {}

// record 结合类型匹配 依然需要通过方法获取属性
private void print(Object object) {
  if (object instanceof Position position) {
    int x =  position.x();
    int y =  position.y();
  } 
}

JEP 405中我们可以这样:

private void print(Object object) {
  if (object instanceof Position(int x, int y)) {
      // 直接使用 x 和 y
  } 
}

当然这仅仅是 JEP 405 的一小部分,该特性也可以应用到switch语句,甚至是嵌套条件中。

JEP 422 Linux/RISC-V Port

由于 RISC-V 指令集架构的硬件越来越多,从Java 19开始提供相应架构的端口。

RISC-V是一个免费和开源的 RISC 指令集架构 (ISA),最初由加州大学伯克利分校设计,现在在RISC-V International的赞助下合作开发。它已经被广泛的语言工具链支持。随着 RISC-V 硬件的日益普及,JDK 的移植将是有价值的。

JEP 424 Foreign Function & Memory API

通过该特性,Java 程序可以通过 API 与 Java 运行时之外的代码和数据进行互操作。通过有效地调用外部函数(即JVM之外的代码)和安全地访问外部内存(即不受 JVM 管理的内存),API 使 Java 程序能够调用 native 库并处理 native 数据,比使用JNI更加安全。这个JEP并不是第一次预览,从JDK 14开始陆续相关的特性都经过孵化和预览,本次是对以往的相关预览特性的改进。

JEP 425 Virtual Threads

虚拟线程,关于虚拟线程之前胖哥有文章进行来专门讲解科普,有兴趣可以通过进行了解。

Java 19 正式发布,改善多线程、并发编程难度-LMLPHP

      传统线程和虚拟线程

在本次 Java 19 中虚拟线程正式以预览的状态亮相,这能够简化对多线程的操作,让以往“昂贵”的线程更加“廉价”。

JEP 426 Vector API

引入一个 API 来表达向量计算,该计算可以在运行时可靠地编译为支持的 CPU 架构上的最佳向量指令,从而实现优于等效标量计算的性能。这个特性已经算老面孔了,已经是第四次预览了。

JEP 427 Pattern Matching for switch

switch语句的匹配模式,目前还没有转正,这是它第三次预览。胖哥已经多次介绍该特性,可以去胖哥往期JDK发布的文章看看。

JEP 428 Structured Concurrency

结构化并发,听起来很厉害的样子。通过引入用于结构化并发的 API 来简化多线程编程。结构化并发将在不同线程中运行的多个任务视为单个工作单元,从而简化错误处理和取消,提高可靠性并增强可观察性。这是一个孵化 API 。

结构化并发 API 的主体类是StructuredTaskScope。此类允许开发人员将任务构建为一系列并发子任务,并将它们作为一个单元进行协调。子任务在它们自己的线程中执行,方法是将它们单独分叉(fork),然后将它们作为一个单元加入,并可能将它们作为一个单元取消( cancel )。子任务的成功结果或异常由父任务聚合和处理。StructuredTaskScope将子任务或分叉的生命周期限制在明确的词法范围内,这样我们可以像写单线程代码一样来写多线程代码。官方给来一个例子:

Response handle() throws ExecutionException, InterruptedException {
    try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {
        Future<String>  user  = scope.fork(() -> findUser());
        Future<Integer> order = scope.fork(() -> fetchOrder());

        scope.join();           // Join both forks
        scope.throwIfFailed();  // ... and propagate errors

        // Here, both forks have succeeded, so compose their results
        return new Response(user.resultNow(), order.resultNow());
    }
}

Java 19 正式发布,改善多线程、并发编程难度-LMLPHP

09-21 19:01