首页 > 其他分享 >JDK21来了!附重要更新说明

JDK21来了!附重要更新说明

时间:2023-09-18 10:22:29浏览次数:43  
标签:JDK21 thread int 更新 说明 线程 threads ZGC OS

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 method
    SequencedCollection<E> reversed();
    // methods promoted from Deque
    void 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 methods
    SequencedMap<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 NavigableMap
    Entry<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是最好的语言"

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

                                 "生产力才是决定语言生死的关键"
  •  
  •  
  •  参考资料:https://openjdk.org/projects/jdk/21/
  •  
  •  

   关注微信公众号,查看更多技术文章。

标签:JDK21,thread,int,更新,说明,线程,threads,ZGC,OS
From: https://www.cnblogs.com/dafanjoy/p/17709944.html

相关文章

  • MySQL实战实战系列 02 日志系统:一条SQL更新语句是如何执行的?
    前面我们系统了解了一个查询语句的执行流程,并介绍了执行过程中涉及的处理模块。相信你还记得,一条查询语句的执行过程一般是经过连接器、分析器、优化器、执行器等功能模块,最后到达存储引擎。 那么,一条更新语句的执行流程又是怎样的呢? 之前你可能经常听DBA同事说,MySQL可以......
  • TienChin 渠道管理-更新渠道接口开发
    ChannelController/***修改渠道*/@PreAuthorize("hasPermission('tienchin:channel:edit')")@Log(title="渠道管理",businessType=BusinessType.UPDATE)@PutMappingAjaxResultedit(@Validated@RequestBodyChannelVOchannelVO){......
  • 个人项目-java实现论文查重(更新中)
    本次作业GitHub项目链接:https://github.com/zzz-muxin/PlagiarismCheck作业详情这个作业属于哪个课程工程概论这个作业要求在哪里作业要求这个作业的目标学会利用GitHub进行项目开发,完成一个工程项目开发的详细过程需求题目:论文查重描述如下:设计一个论......
  • buu pwn wp(持续更新)
    1、warmup_csaw_2016main函数如下__int64__fastcallmain(inta1,char**a2,char**a3){chars[64];//[rsp+0h][rbp-80h]BYREFcharv5[64];//[rsp+40h][rbp-40h]BYREFwrite(1,"-WarmUp-\n",0xAuLL);write(1,"WOW:",4uLL);......
  • 三国杀说明书
    三国杀说明书初衷本系统设计时已经最大程度考虑后继兼容性即不需要改变主代码框架也可以实现增加手牌种类(成员函数指针),增加英雄及其技能(继承Player类),增加游戏人数和玩法(存储玩家的和绝大多数函数设计上都是面向服务端的)但是该作品只是demo所以这次只实现了一个固定英雄郭嘉(......
  • 沉寂 7 年的项目突然更新!zabbix 安装更加简单!
    项目地址https://github.com/X-Mars/Quick-Installation-ZABBIX项目介绍zabbix6.0一键安装脚本,目标支持所有的主流操作系统支持的操作系统:rockylinux8.0、rockylinux9.0、ubuntu20、ubuntu22、centos7即将支持的操作系统:centos8、openeuler20、openeuler22......
  • CTF BugKu平台——Crypto篇刷题记录(后续更新)
    (CTFBugKu平台——Crypto篇)前言记录一下密码学的刷题记录也是为了更好的巩固自己基本有的解码都附有超链接希望大家能顺利通关感谢观看!抄错的字符:描述:老师让小明抄写一段话,结果粗心的小明把部分数字抄成了字母,还因为强迫症把所有字母都换成大写。你能帮小明恢复并......
  • 错误统计(持续更新)
    树直径\(\neq\)最长链+次长链(NTT典中典:for(inti=0;i<n;i++)a[i]=a[i]*b[i]%mod;。事实上是i<lim。典中典2:for(inti=1;i<lim;i++)r[i]=(r[i>>1]>>1)|(1<<L-1)。事实上是r[i]=(r[i>>]>>1)|((i&1)<<L-1)。......
  • web应用及微信小程序版本更新检测方案实践
    背景:随着项目体量越来越大,用户群体越来越多,用户的声音也越来越明显;关于应用发版之后用户无感知,导致用户用的是仍然还是老版本功能,除非用户手动刷新,否则体验不到最新的功能;这样的体验非常不好,于是我们团队针对该问题给出了相应的解决方案来处理;技术栈:vue3+ts+vite+ant-design-......
  • 关于以后的文章更新说明
    主要是考虑到不能完全依赖与第三方的平台的万一以后找不到文件,,,比如照片的连接失效了...该怎么办.是吧....比如md文件怎么找回来是吧所以我还在自己在本地备份了一个博客文件..然后使用Hexo+Github+Cactus搭建的这样的话..就可以完整的保留附件了..但是Github是出于半墙半不......