JDK21来了!附重要更新说明

2023-10-24 21:30
文章标签 更新 说明 重要 jdk21

本文主要是介绍JDK21来了!附重要更新说明,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

JDK21 计划23年9月19日正式发布,虽然一直以来都是“版本随便出,换 8 算我输”,但这么多年这么多版本的折腾,如果说之前的 LTS版本JDK17你还觉得不香,那 JDK21还是有必要关注一下,因为会有一批重要更新发布到生产环境中,特别是千呼万唤的虚拟线程,虽然说这东西我感觉不需要的用不到,需要的早都转go了,哈哈,但作为近几年JDK一个“重大”的更新,在实际开发应用中还是是有很大价值的。所以这篇文章主要提取了这次更新中个人感觉比较有价值的几点做个基本的介绍,想要尝鲜的同学可以看下。

Visual Threads (虚拟线程) -JEP 444

先看下官方对虚拟线程(Visual Threads)描述:

Today, every instance of java.lang.Thread in the JDK is a platform thread. A platform thread runs Java code on an underlying OS thread and captures the OS thread for the code's entire lifetime. The number of platform threads is limited to the number of OS threads.

A virtual thread is an instance of java.lang.Thread that runs Java code on an underlying OS thread but does not capture the OS thread for the code's entire lifetime. This means that many virtual threads can run their Java code on the same OS thread, effectively sharing it. While a platform thread monopolizes a precious OS thread, a virtual thread does not. The number of virtual threads can be much larger than the number of OS threads.

Virtual threads are a lightweight implementation of threads that is provided by the JDK rather than the OS. They are a form of user-mode threads, which have been successful in other multithreaded languages (e.g., goroutines in Go and processes in Erlang). User-mode threads even featured as so-called "green threads" in early versions of Java, when OS threads were not yet mature and widespread. However, Java's green threads all shared one OS thread (M:1 scheduling) and were eventually outperformed by platform threads, implemented as wrappers for OS threads (1:1 scheduling). Virtual threads employ M:N scheduling, where a large number (M) of virtual threads is scheduled to run on a smaller number (N) of OS threads.

总结下就是之前java中的线程是“platform thread”即平台线程,它由操作系统线程为基础,按照1:1的模式调度,这导致线程的创建与执行都是很耗资源的,同时数量也受系统的约束;但新的虚拟线程则是由JDK提供,你可以把它看作是在平台线程基础上创建的“一批”线程,它们有效地共享所属的平台线程也就是操作系统线程的资源,从而提升系统利用率,并不受数量限制。

目标描述:

1、Enable server applications written in the simple thread-per-request style to scale with near-optimal hardware utilization.

可以每个请求开启一个虚拟线程,实现简单直接的同时可以最大程度的提升硬件利用率;

2、Enable existing code that uses the java.lang.Thread API to adopt virtual threads with minimal change.

之前的多线程实现代码可以在较小的改动下完成向虚拟线程的迁移;

3、Enable easy troubleshooting, debugging, and profiling of virtual threads with existing JDK tools.

使用现有JDK工具可以完成虚拟线程的代码调试、分析与问题定位;

说白了就是现在我们不用怎么改代码就可以创建一个轻量级的虚拟线程,实现简单同时还能够充分发挥硬件性能。

一个简单的代码示例

try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {IntStream.range(0, 10000).forEach(i -> {executor.submit(() -> {Thread.sleep(Duration.ofSeconds(1));return i;});});
}  // executor.close() is called implicitly, and waits

SequencedCollection Interface(顺序集合 接口)

兄弟们,作为一个天天CRUD,CPU跑不满20%的程序员, 相比上面的虚拟线程,这次关于集合类接口的更新我感觉更实在一些

JDK21中我们常用的Set、List、Deque与Map集合类分别继承实现了SequencedCollection、 SequencedMap 接口,为我们执行一些顺序性操作比如获取头尾值提供了各类接口方法

继承关系如下图所示:

接口定义如下

interface SequencedCollection<E> extends Collection<E> {// new methodSequencedCollection<E> reversed();// methods promoted from Dequevoid addFirst(E);void addLast(E);E getFirst();E getLast();E removeFirst();E removeLast();
}
interface SequencedSet<E> extends Set<E>, SequencedCollection<E> {SequencedSet<E> reversed();    // covariant override
}
interface SequencedMap<K,V> extends Map<K,V> {// new methodsSequencedMap<K,V> reversed();SequencedSet<K> sequencedKeySet();SequencedCollection<V> sequencedValues();SequencedSet<Entry<K,V>> sequencedEntrySet();V putFirst(K, V);V putLast(K, V);// methods promoted from NavigableMapEntry<K, V> firstEntry();Entry<K, V> lastEntry();Entry<K, V> pollFirstEntry();Entry<K, V> pollLastEntry();
}

Record Patterns (记录模式)-JEP 440

这个更新主要简化了类型判断与赋值的使用,类型判断后无需显式强制转换且如果模式匹配,变量被初始化为要匹配的模板值, 这个说起来比较拗口,结合代码大家理解下,我感觉还是挺有用的,这里我把JDK8 JDK17 JDK21 的实现进行一个对比,大家就明白了。

// As of Java 8
record Point(int x, int y) {}static void printSum(Object obj) {if (obj instanceof Point) {Point p = (Point) obj;int x = p.x();int y = p.y();System.out.println(x+y);}
}
// As of Java 16
record Point(int x, int y) {}static void printSum(Object obj) {if (obj instanceof Point p) {int x = p.x();int y = p.y();System.out.println(x+y);}
}
// As of Java 21
static void printSum(Object obj) {if (obj instanceof Point(int x, int y)) {System.out.println(x+y);}
}

Pattern Matching for switch (switch模式匹配) – JEP 441

switch 的模式匹配可以与Record Patterns结合使用 允许在任何对象上制定 switch 语句和表达式。看一下代码例子:

static String formatterPatternSwitch(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);case Position(int x, int y)   -> String.format("String %s,String %s", x,y);default        -> obj.toString();};
}

同时当编译器判断所有分支都已涵盖时,switch不再需要分支default,如下面的代码

void flyJava21(Direction direction) { switch (direction) {case CompassDirection.NORTH -> System.out.println("Flying north"); case CompassDirection.SOUTH -> System.out.println("Flying south");case CompassDirection.EAST -> System.out.println("Flying east");case CompassDirection.WEST -> System.out.println("Flying west"); case VerticalDirection.UP -> System.out.println("Gaining altitude"); case VerticalDirection.DOWN -> System.out.println("Losing altitude"); } 
}

Generational ZGC(分代式 ZGC) -JEP 439

主要是增加了对分代的支持,提高垃圾回收的性能,看下整体描述

To ensure a smooth succession, we will initially make Generational ZGC available alongside non-generational ZGC. The -XX:+UseZGC command-line option will select non-generational ZGC; to select Generational ZGC, add the -XX:+ZGenerational option:

使用命令行选项 -XX:+UseZGC 将选择非分代式 ZGC;要选择分代式 ZGC,需要添加 -XX:+ZGenerational 选项。

$ java -XX:+UseZGC -XX:+ZGenerational ...

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.

总结就是当前版本中如果想使用ZGC,命令行选项增加 -XX:+UseZGC,但默认是非分代式GC;要使用分代式ZGC ,需要改为 $ java -XX:+UseZGC -XX:+ZGenerational ,而在后续的版本中会默认改为分代GC。

以上就是JDK21版本中我感觉一些有价值的更新,如果大家希望能够更进一步的了解还是要去官网https://openjdk.org/projects/jdk/21/ 自行查看,并在发布之后在使用中实际验证。

之所以有这次总结,主要还是有感于java近年来受到其他各类语言的冲击,颇有垂垂老矣的感觉,让我这个C#出身的javaer又想起了一段不好的回忆,哈哈,所以看看这次的更新是否能给点力, 当前java语言的下行趋势也可以说是国内IT行业兴衰起伏的一个侧面写照,当然作为一个提供生产力的编程语言,围绕java建立起的整个完整、稳定、强大的生态仍然会在它适合的领域起到重要的作用,这是一时半会无法改变的,但你指望靠它干到退休估计连收了学费的培训机构也不敢这样说,程序员的职业寿命从来不是某种编程语言决定的。最后我还是想说入行的菜鸟才纠结于语言优劣,成熟老手知道这早有定论,让我们大声喊出:   

                                     "PHP是最好的语言"

这不是玩梗,因为从某种角度上讲: 

                                 "生产力才是决定语言生死的关键"

参考资料: JDK 21 

这篇关于JDK21来了!附重要更新说明的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/277882

相关文章

在Dockerfile中copy和add的区别及说明

《在Dockerfile中copy和add的区别及说明》COPY和ADD都是Dockerfile中用于文件复制的命令,但COPY仅用于本地文件或目录的复制,不支持自动解压缩;而ADD除了复制本地文件或... 目录在dockerfile中,copy 和 add有什么区别?COPY 命令ADD 命令总结在Doc

解读Pandas和Polars的区别及说明

《解读Pandas和Polars的区别及说明》Pandas和Polars是Python中用于数据处理的两个库,Pandas适用于中小规模数据的快速原型开发和复杂数据操作,而Polars则专注于高效数据... 目录Pandas vs Polars 对比表使用场景对比Pandas 的使用场景Polars 的使用

Spring Boot Actuator使用说明

《SpringBootActuator使用说明》SpringBootActuator是一个用于监控和管理SpringBoot应用程序的强大工具,通过引入依赖并配置,可以启用默认的监控接口,... 目录项目里引入下面这个依赖使用场景总结说明:本文介绍Spring Boot Actuator的使用,关于Spri

Linux中shell解析脚本的通配符、元字符、转义符说明

《Linux中shell解析脚本的通配符、元字符、转义符说明》:本文主要介绍shell通配符、元字符、转义符以及shell解析脚本的过程,通配符用于路径扩展,元字符用于多命令分割,转义符用于将特殊... 目录一、linux shell通配符(wildcard)二、shell元字符(特殊字符 Meta)三、s

java脚本使用不同版本jdk的说明介绍

《java脚本使用不同版本jdk的说明介绍》本文介绍了在Java中执行JavaScript脚本的几种方式,包括使用ScriptEngine、Nashorn和GraalVM,ScriptEngine适用... 目录Java脚本使用不同版本jdk的说明1.使用ScriptEngine执行javascript2.

Redis缓存问题与缓存更新机制详解

《Redis缓存问题与缓存更新机制详解》本文主要介绍了缓存问题及其解决方案,包括缓存穿透、缓存击穿、缓存雪崩等问题的成因以及相应的预防和解决方法,同时,还详细探讨了缓存更新机制,包括不同情况下的缓存更... 目录一、缓存问题1.1 缓存穿透1.1.1 问题来源1.1.2 解决方案1.2 缓存击穿1.2.1

Linux Mint Xia 22.1重磅发布: 重要更新一览

《LinuxMintXia22.1重磅发布:重要更新一览》Beta版LinuxMint“Xia”22.1发布,新版本基于Ubuntu24.04,内核版本为Linux6.8,这... linux Mint 22.1「Xia」正式发布啦!这次更新带来了诸多优化和改进,进一步巩固了 Mint 在 Linux 桌面

SpringCloud配置动态更新原理解析

《SpringCloud配置动态更新原理解析》在微服务架构的浩瀚星海中,服务配置的动态更新如同魔法一般,能够让应用在不重启的情况下,实时响应配置的变更,SpringCloud作为微服务架构中的佼佼者,... 目录一、SpringBoot、Cloud配置的读取二、SpringCloud配置动态刷新三、更新@R

Redis分布式锁使用及说明

《Redis分布式锁使用及说明》本文总结了Redis和Zookeeper在高可用性和高一致性场景下的应用,并详细介绍了Redis的分布式锁实现方式,包括使用Lua脚本和续期机制,最后,提到了RedLo... 目录Redis分布式锁加锁方式怎么会解错锁?举个小案例吧解锁方式续期总结Redis分布式锁如果追求

结构体和联合体的区别及说明

《结构体和联合体的区别及说明》文章主要介绍了C语言中的结构体和联合体,结构体是一种自定义的复合数据类型,可以包含多个成员,每个成员可以是不同的数据类型,联合体是一种特殊的数据结构,可以在内存中共享同一... 目录结构体和联合体的区别1. 结构体(Struct)2. 联合体(Union)3. 联合体与结构体的