Java终于开始引入虚拟线程(协程)了

系统运维2025-11-05 11:17:31824

高并发、终于多线程一直是开始Java编程中的难点,也是引入面试题中的要点。Java开发者也一直在尝试使用多线程来解决应用服务器的虚拟线程协程并发问题。但是终于多线程并不容易,为此一个新的开始技术出现了,这就是引入虚拟线程。

传统多线程的虚拟线程协程痛点

但是编写多线程代码是非常不容易的,难以控制的终于执行顺序,共享变量的开始线程安全性,异常可观察性等等都是引入多线程编程的难点。

Java终于开始引入虚拟线程(协程)了

如果每个请求在请求的虚拟线程协程持续时间内都在一个线程中处理,那么为了提高应用程序的终于吞吐量,线程的开始数量必须随着吞吐量的增长而增长。b2b供应网不幸的引入是线程是稀缺资源,创建一个线程的代价是昂贵的,即使引入了池化技术也无法降低新线程的创建成本,而且 JDK 当前的线程实现将应用程序的吞吐量限制在远低于硬件可以支持的水平。

为此很多开发人员转向了异步编程,例如CompletableFuture或者现在正热的反应式框架。但是这些技术要么摆脱不了“回调地狱”,要么缺乏可观测性。

解决这些痛点、增强Java平台的和谐,实现每个请求使用独立线程(thread-per-request style)这种风格成为必要之举。能否实现一种“成本低廉”的虚拟线程来映射到系统线程以减少对系统线程的直接操作呢?思路应该是没问题的!于是Java社区发起了关于虚拟线程的JEP 425[1]提案。

虚拟线程

虚拟线程(virtual threads)应该非常廉价而且可以无需担心系统硬件资源被大量创建,并且不应该被池化。WordPress模板应该为每个应用程序任务创建一个新的虚拟线程。因此,大多数虚拟线程将是短暂的并且具有浅层调用堆栈,只执行单个 HTTP 客户端调用或单个 JDBC 查询。与之对应的平台线程( Platform Threads,也就是现在传统的JVM线程 )是重量级且昂贵的,因此通常必须被池化。它们往往寿命长,有很深的调用堆栈,并且在许多任务之间共享。

总而言之,虚拟线程保留了与 Java 平台的设计相协调的、可靠的每请求线程样式,同时优化了硬件的利用。使用虚拟线程不需要学习新概念,甚至需要改掉现在操作多线程的习惯,使用更加容易上手的API、兼容以前的企商汇多线程设计、并且丝毫不会影响代码的拓展性。

平台线程和虚拟线程的不同

为了更好理解这一个设计,草案对这两种线程进行了比较。

现在的线程现在每个java.lang.Thread都是一个平台线程,平台线程在底层操作系统线程上运行 Java 代码,并在代码的整个生命周期内捕获操作系统线程。平台线程数受限于 OS 线程数。

平台线程

并不会因为加入虚拟线程而退出历史舞台。

未来的虚拟线程

虚拟线程是由 JDK 而不是操作系统提供的线程的轻量级实现。它们是用户模式线程的一种形式,在其他多线程语言中已经成功(比如Golang中的协程和Erlang中的进程)。虚拟线程采用 M:N 调度,其中大量 (M) 虚拟线程被调度为在较少数量 (N) 的 OS 线程上运行。JDK 的虚拟线程调度程序是一种ForkJoinPool工作窃取的机制,以 FIFO 模式运行。

我们可以很随意地创建10000个虚拟线程:

// 预览代码

try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {

IntStream.range(0, 10_000).forEach(i -> {

executor.submit(() -> {

Thread.sleep(Duration.ofSeconds(1));

return i;

});

});

}

无需担心硬件资源是否扛得住,反过来如果你使用Executors.newCachedThreadPool()创建10000个平台线程,在大多数操作系统上很容易因资源不足而崩溃。

为吞吐量而设计

但是这里依然要说明一点,虚拟线程并非为了提升执行速度而设计。它并不比平台线程速度快,它们的存在是为了提供规模(更高的吞吐量),而不是速度(更低的延迟)。它们的数量可能比平台线程多得多,因此根据利特尔定律,它们可以实现更高吞吐量所需的更高并发性。

换句话说,虚拟线程可以显著提高应用程序吞吐量

并发任务的数量很高(超过几千个),并且工作负载不受 CPU 限制,因为在这种情况下,拥有比处理器内核多得多的线程并不能提高吞吐量。

虚拟线程有助于提高传统服务器应用程序的吞吐量,正是因为此类应用程序包含大量并发任务,这些任务花费大量的时间等待。

增强可观测性

编写清晰的代码并不是全部。对正在运行的程序状态的清晰表示对于故障排除、维护和优化也很重要,JDK 长期以来一直提供调试、分析和监视线程的机制。在虚拟线程中也会增强代码的可观测性,让开发人员更好地调试代码。

新的线程API

为此增加了新的线程API设计,目前放出的部分如下:

Thread.Builder 线程构建器。ThreadFactory 能批量构建相同特性的线程工厂。Thread.ofVirtual() 创建一个虚拟线程。Thread.ofPlatform() 创建一个平台线程。Thread.startVirtualThread(Runnable) 一种创建然后启动虚拟线程的便捷方式。Thread.isVirtual() 测试线程是否是虚拟线程。

还有很多就不一一演示了,有兴趣的自行去看JEP425。

总结

协程在Java社区已经呼唤了很久了,现在终于有了实质性的动作,这是一个非常重要的特性。不过这个功能涉及的东西还是很多的,包括平台线程的兼容性、对ThreadLocal的一些影响、对JUC的影响。可能需要多次预览才能最终落地,不过这已经是很大的进步了,起码距离实装已经不远了,胖哥可能赶不上那个时候了,不过很多年轻的同学应该能够赶上。

本文地址:http://www.bzuk.cn/news/550a39099059.html
版权声明

本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。

全站热门

复制代码代码如下:sudo hdparm -B 128 /dev/sda 假如设为254,硬盘温度甚至会攀升到45度,虽然这仍是一个正常的硬盘温度,但对于笔记本用户来说,靠近硬盘处的发热量是很容易察觉到的. 复制代码代码如下:hdparm -B 192 /dev/sda 复制代码代码如下:/dev/sda { 复制代码代码如下:sudo smartctl -a /dev/sda | grep Load_Cycle_Count 假如Load_Cycle_Count值每分钟都在增加,这时你应该把APM值设回原来的254,方法同上可以在/etc/hdparm.conf里修改. 执行命令复制代码代码如下: sudo hdparm -B 254 /dev/sda 即时生效, 配置在重启后生效. 因为磁头频繁的Load/Unload同样会影响硬盘寿命,一般硬盘设计能承受的加载循环计数Load_Cycle_Count最多为600000次.

可持续农业的物联网需要可靠的连接

物联网在零售中有哪些实际应用?

通过物联网解决方案提高制造运营效率

slim 是一款轻便的linux图形窗口桌面管理工具,它设置简单,启动迅速,占很少内存,是一个不错的选择。软件名称:SlimComputer(电脑卸载提速软件) v1.3 英文官方安装版 软件大小:369KB更新时间:2015-01-271、使用命令安装slim。sudo apt-get install slim2、安装完成后slim 默认有5个主题,选择一个自己喜欢的。3、如何让slim使用自己喜欢的主题,slim的配置文件在/etc/slim.conf4、使用root权限打开slim.conf,开始编辑。5、将图中的圈出来的地方改为你喜欢的slim主题的文件夹名称,改完后保存退出。6、使用 slim -p slim主题路径(/usr/share/slim/themes/某一主题)注意事项:编辑配置文件时要用root权限。

物联网在构建未来智能电网中的作用

工业物联网的未来原来是这样啊!

物联网使工业工作场所更安全的三种方法

友情链接

滇ICP备2023006006号-33