JDK21 性能提升 20 倍
创始人
2025-07-04 08:31:22
0

大家好,我是了不起。

JDK21 发布已经过去1个月时间了,除了每次发版必然更新的GC机制,和一些增强功能外,还引入了一个全新的概念——虚拟线程。

什么是虚拟线程

先来看一下官方对虚拟线程(Visual Threads)的描述(已翻译):

如今,JDK中java.lang.Thread的每个实例都是一个平台线程。平台线程在底层操作系统线程上运行Java代码,并在代码的整个生命周期中捕获操作系统线程。平台线程的数量限制为操作系统线程的数量。

虚拟线程是java.lang.thread的一个实例,它在底层操作系统线程上运行java代码,但在代码的整个生命周期内不会捕获该操作系统线程。这意味着许多虚拟线程可以在同一个操作系统线程上运行Java代码,从而有效地共享代码。

虽然平台线程独占了宝贵的操作系统线程,但虚拟线程却没有。虚拟线程的数量可以比操作系统线程的数量大得多。

虚拟线程是JDK而不是OS提供的线程的轻量级实现。它们是用户模式线程的一种形式,在其他多线程语言中也很成功(例如Go中的goroutines和Erlang中的processes)。用户模式线程甚至在早期版本的Java中被称为“绿色线程”,当时操作系统线程还不成熟和广泛使用。然而,Java的绿色线程都共享一个操作系统线程(M:1调度),并且最终被平台线程所超越,后者被实现为操作系统线程的包装器(1:1调度)。虚拟线程采用M:N调度,其中大量(M)虚拟线程被调度在少量(N)OS线程上运行。

简而言之,现在我们可以轻松地创建一个轻量级的虚拟线程,实现简单性,同时充分发挥硬件性能。

可以概括为: 轻量、多路复用、开销极小、异步编程、可移植性

测试

开始一个简单的测试:1万并发阻塞1秒模仿web连接池,使用Thread.sleep(1) 模拟IO操作需要的时间。

public static void main(String[] args) throws InterruptedException {
    long l = System.currentTimeMillis();
//    normal();
    virtual();
    System.out.println(System.currentTimeMillis() - l);
}

先使用常规线程池方式运行:

public static void normal() throws InterruptedException {
    ExecutorService executor = Executors.newFixedThreadPool(200);
    for (int i=0; i < 10000; i++) {
        executor.execute(() -> {
            try {
                System.out.println("normal");
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
    }
    executor.shutdown();
    executor.awaitTermination(100, java.util.concurrent.TimeUnit.SECONDS);
}

得到如下结果:

图片图片

使用 JDK21 虚拟线程池运行:

public static void virtual() throws InterruptedException {
    ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor();
    for (int i=0; i < 10000; i++) {
        executor.execute(() -> {
            try {
                System.out.println("jdk21");
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
    }
    executor.shutdown();
    executor.awaitTermination(100, java.util.concurrent.TimeUnit.SECONDS);
}

得到如下结果:

图片图片

20多倍的提速!!!

我不理解,但我大受震撼!!!

如果有朋友想自己测试一下虚拟线程,或者JDK21的其他新特性,可以尝试一下哦~

JDK21 官网下载链接:https://download.oracle.com/graalvm/21/latest/graalvm-jdk-21_windows-x64_bin.zip

目前虚拟线程还属于预览版本,没有正式启用。如果是IDEA 开发工具,在启动的时候,需要配置VM参数 --enable-preview

图片图片

小结

经过测试,在该例子中,Executors.newFixedThreadPool( size ); size的值越大,普通的线程池用时越短,在线程池的大小开放到 10000后,用时几乎一样。

应该是本例的IO操作是Thread.sleep的缘故,所以不会占用CPU资源。

传统的线程池,一般我们会指定核心线程数量为 CPU核心数*4,最大线程数为 CPU核心数*8,而在虚拟线程池中,不需要指定线程数,JDK会自动根据资源占用情况,创建合适数量的线程,追求更高的吞吐量。

听说springboot3.2.0版本开始,springboot要把webflux底层也改成虚拟线程了,不知道以后会不会把所有的关于异步线程的地方都改成虚拟线程。

了不起是觉得这个虚拟线程真是个好东西,简单易用,再也不纠结怎么配置线程池,根据硬件自适应,效率极高。

现在Spring6是基于JDK17的,不知道下个大版本更新会不会直接更新到有虚拟线程稳定发布的JDK版本,期待!

相关内容

热门资讯

PHP新手之PHP入门 PHP是一种易于学习和使用的服务器端脚本语言。只需要很少的编程知识你就能使用PHP建立一个真正交互的...
网络中立的未来 网络中立性是什... 《牛津词典》中对“网络中立”的解释是“电信运营商应秉持的一种原则,即不考虑来源地提供所有内容和应用的...
各种千兆交换机的数据接口类型详... 千兆交换机有很多值得学习的地方,这里我们主要介绍各种千兆交换机的数据接口类型,作为局域网的主要连接设...
粉嫩如何诠释霸道 东芝M805... “霸道粉”是个什么玩意东芝M805拿过来的时候,笔者扑哧笑了,不是笑这款笔记本,而是笑这款产品的颜色...
什么是大数据安全 什么是大数据... 在《为什么需要大数据安全分析》一文中,我们已经阐述了一个重要观点,即:安全要素信息呈现出大数据的特征...
如何利用交换机和端口设置来管理... 在网络管理中,总是有些人让管理员头疼。下面我们就将介绍一下一个网管员利用交换机以及端口设置等来进行D...
全面诠释网络负载均衡 负载均衡的出现大大缓解了服务器的压力,更是有效的利用了资源,提高了效率。那么我们现在来说一下网络负载...
如何允许远程连接到MySQL数... [[277004]]【51CTO.com快译】默认情况下,MySQL服务器仅侦听来自localhos...
30分钟搞定iOS自定义相机 最近公司的项目中用到了相机,由于不用系统的相机,UI给的相机切图,必须自定义才可以。就花时间简单研究...
Intel将Moblin社区控... 本周二,非营利机构Linux基金会宣布,他们将担负起Moblin社区的管理工作,而这之前,Mobli...