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

相关文章

Linux内核定时器使用及说明

《Linux内核定时器使用及说明》文章详细介绍了Linux内核定时器的特性、核心数据结构、时间相关转换函数以及操作API,通过示例展示了如何编写和使用定时器,包括按键消抖的应用... 目录1.linux内核定时器特征2.Linux内核定时器核心数据结构3.Linux内核时间相关转换函数4.Linux内核定时

Java之ServerSocket使用及说明

《Java之ServerSocket使用及说明》本文介绍了Java中ServerSocket类的使用方法,包括创建ServerSocket对象、绑定端口、监听连接请求、接受连接、关闭连接等常用方法,还... 目录前言常用方法使用案例1.实现TCP2.实现UDP总结前言Java中的ServerSocket

Java Exception与RuntimeException使用及说明

《JavaException与RuntimeException使用及说明》:本文主要介绍JavaException与RuntimeException使用及说明,具有很好的参考价值,希望对大家有所... 目录简介ExceptionRuntimeException自定义异常选择继承Exception(受检异常)

MySQL中存储过程(procedure)的使用及说明

《MySQL中存储过程(procedure)的使用及说明》存储过程是预先定义的SQL语句集合,可在数据库中重复调用,它们提供事务性、高效性和安全性,MySQL和Java中均可创建和调用存储过程,示例展... 目录概念示例1示例2总结概念存储过程:在数据库中预先定义好一组SQL语句,可以被程序反复调用。

Linux join命令的使用及说明

《Linuxjoin命令的使用及说明》`join`命令用于在Linux中按字段将两个文件进行连接,类似于SQL的JOIN,它需要两个文件按用于匹配的字段排序,并且第一个文件的换行符必须是LF,`jo... 目录一. 基本语法二. 数据准备三. 指定文件的连接key四.-a输出指定文件的所有行五.-o指定输出

JDK21对虚拟线程的几种用法实践指南

《JDK21对虚拟线程的几种用法实践指南》虚拟线程是Java中的一种轻量级线程,由JVM管理,特别适合于I/O密集型任务,:本文主要介绍JDK21对虚拟线程的几种用法,文中通过代码介绍的非常详细,... 目录一、参考官方文档二、什么是虚拟线程三、几种用法1、Thread.ofVirtual().start(

Redis中Hash从使用过程到原理说明

《Redis中Hash从使用过程到原理说明》RedisHash结构用于存储字段-值对,适合对象数据,支持HSET、HGET等命令,采用ziplist或hashtable编码,通过渐进式rehash优化... 目录一、开篇:Hash就像超市的货架二、Hash的基本使用1. 常用命令示例2. Java操作示例三

Redis中Set结构使用过程与原理说明

《Redis中Set结构使用过程与原理说明》本文解析了RedisSet数据结构,涵盖其基本操作(如添加、查找)、集合运算(交并差)、底层实现(intset与hashtable自动切换机制)、典型应用场... 目录开篇:从购物车到Redis Set一、Redis Set的基本操作1.1 编程常用命令1.2 集

Python sys模块的使用及说明

《Pythonsys模块的使用及说明》Pythonsys模块是核心工具,用于解释器交互与运行时控制,涵盖命令行参数处理、路径修改、强制退出、I/O重定向、系统信息获取等功能,适用于脚本开发与调试,需... 目录python sys 模块详解常用功能与代码示例获取命令行参数修改模块搜索路径强制退出程序标准输入

MySQL之复合查询使用及说明

《MySQL之复合查询使用及说明》文章讲解了SQL复合查询中emp、dept、salgrade三张表的使用,涵盖多表连接、自连接、子查询(单行/多行/多列)及合并查询(UNION/UNIONALL)等... 目录复合查询基本查询回顾多表查询笛卡尔积自连接子查询单行子查询多行子查询多列子查询在from子句中使