虚拟线程目前不推荐上生产的个人思考

1.pin 线程引发的问题比预期严重,需要修改的库繁多

截止目前 Java 21 虚拟线程一些比较严重的 Bug:

  1. Thread.HoldsLock(Object) 这个方法,如果是虚拟线程调用,会在平台线程获取到锁之后,就算切换虚拟线程,也会返回 true:bugs.openjdk.org/browse/JDK-...

  2. 默认使用的 ForkJoinPool.common 线程池,如果全部 pin 住,问题很严重。比如synchronized 块外有与块内争用的资源,可能会导致死锁(这个与原来的线程池池化死锁类似)。主要是 monitor enter 的机制与虚拟线程的 Continuation 设计以及 ForkJoinPool 的设计目前不太兼容:bugs.openjdk.org/browse/JDK-...

目前看来,synchronized pin 线程的问题比预期的更严重,很多库,包括 JDK 库本身可能都要兼容:

  1. JDK 库本身:

(1)需要重新看看 AQS 的设计与虚拟线程的兼容性,尤其是队列,防止出现队列调度死锁

(2)需要审查下 ForkJoinPool 的设计,将 ForkJoinPool 作为默认的 Carrier 线程池,是否合适。因为工作窃取导致调度设计困难,并且,ForkJoinPool 天生不支持 Go 那种遇到 Pin 线程新起一个线程的解决方案。我个人觉得,需要那种能手动指定虚拟线程的负载线程池的方案

(3)很多 synchronized 的代码是否要重写,尤其是常用的数据结构以及输出流的地方。

  1. 各种 Java 库的兼容:日常开发离不开 JDBC 库,但是官方的 JDBC 库里面很多 synchronized 以及与虚拟线程的设计不好兼容的没必要的同步队列。

  2. 其实可以考虑 Java 重构 synchronized 不 pin 线程,但是不知道要什么时候了。

2. 非抢占设计与切换消耗不适合 CPU 密集计算型任务:

复制代码
(1)非抢占式设计:虚拟线程只会在遇到阻塞的时候与底层平台线程分离切换,否则不会切换。比如你有 4 核,同时启动 8 个平台线程的计算任务,每个任务基本上进度是一样的。同时启动 8 个虚拟线程的计算任务,则是先执行 4 个,之后再执行 4 个。

(2)虚拟线程切换的消耗比较大,虽然已经做了很多优化(Continuation 的堆栈增量复制,按需复制,优化虚拟线程 GC 根引用扫描),但是消耗还是很大,下面是一个平台线程执行与虚拟线程执行计算任务的 CPU 采样对比:

3. ThreadLocal很常用很难去掉,ScopedLocal 不能解决所有问题

第一个问题是内存占用太大导致吞吐量下降:ThreadLocal 虽然底层的 Map 是 WeakReference 的,但是设计之初是考虑 Thread 数量有限。在有虚拟线程很大量的时候,这个 Map 是非常消耗内存的。ScopedValue 通过限制作用域,以及值不可变的方式,优化了内存占用的问题。但是,ScopedValue 还处于预览阶段,并且没有解决 ThreadLocal 的所有问题。

没有解决的问题就是第二个问题:之前有很多使用 ThreadLocal 作为资源池的场景(很多库都这么用)。比如说,最早的线程不安全的 SimpleDateFormat(虽然现在已经不怎么用了)。它解决线程不安全的方式,就是或者每次新建一个 SimpleDateFormat,或者使用 ThreadLocal 针对每个线程创建一个独立的。后者肯定消耗比前者小。但是,引入了虚拟线程,就相当于回到了最原来的做法。针对这种资源池的场景(即限制某个线程不安全的资源,每个平台线程创建一个独立使用不并发就行了),其实我们还是想对于平台线程创建。这个对于很多库的影响很多,比如 jackson,jackson 针对这个问题的解决方式是:github.com/FasterXML/j...

其实也不是说用新的 ThreadLocal 去替换,而是换种思路,将对象池化的同时,让程序从池子里获取并在用完的时候放回。相当于明确控制生命周期。但是我们也可以看出,这个对于三方库的改造,也是很大的。

相关推荐
L汐24 分钟前
02 K8s双主安装
java·容器·kubernetes
Code哈哈笑37 分钟前
【图书管理系统】用户注册系统实现详解
数据库·spring boot·后端·mybatis
用手手打人39 分钟前
SpringBoot(一)--- Maven基础
spring boot·后端·maven
jackson凌1 小时前
【Java学习笔记】【第一阶段项目实践】房屋出租系统(面向对象版本)
java·笔记·学习
带刺的坐椅1 小时前
Solon Ai Flow 编排开发框架发布预告(效果预览)
java·ai·solon·dify·solon-flow
2302_809798321 小时前
【JavaWeb】JDBC
java·开发语言·servlet
小刘不想改BUG2 小时前
LeetCode LCR 010 和为 K 的子数组 (Java)
java·算法·leetcode
MeyrlNotFound2 小时前
(二十一)Java集合框架源码深度解析
java·开发语言
正在走向自律2 小时前
2025年、2024年最新版IntelliJ IDEA下载安装过程(含Java环境搭建+Maven下载及配置)
java·jvm·jdk·maven·intellij-idea
不会就选C.2 小时前
【开源分享】健康饮食管理系统(双端+论文)
java·spring boot·开源·毕业设计