Java24虚拟线程在连接池+数据库面前不堪重负


听说Java搞了个叫"虚拟线程"的黑科技?号称能让程序轻松处理百万级请求?今天咱们就来扒一扒它的真面目!
先说说这是啥玩意儿

Java在19版搞了个试验品(预览功能),到21版正式推出了这个"虚拟线程"。简单说就是:

  • 以前:一个请求要用一个真线程(平台线程),线程多了内存吃不消
  • 现在:用虚拟线程假装是真线程,实际在幕后搞"线程共享"
听起来很美好对吧?但实际用起来咋样呢?

我们在一个现实的SpringBoot+ PostgreSQL设置中对它们进行了基准测试。我们的目标是超越炒作,看看JEP 491(它解决了固定)是否真的提高了现实世界的性能。


我们做了个大型真人秀测试

我们测试了以下各项的各种组合:

  • Java 19与Java 24
  • Spring靴子3.3.12 vs 3.5.0(也是4.0.0,但仍在开发中)
  • 平台线程与虚拟线程
  • 轻度到重度并发(20 → 1000个用户)
  • 所有都具有模拟数据库延迟和抖动


测试场景就像学校食堂:

  • 场景A:20个同学打饭,50个打菜窗口(轻松无压力)
  • 场景B:500个饿狼冲食堂,只有20个窗口(开始排队)
  • 场景C:1000个饿狼...(画面太美不敢看)

测试结果让人大跌眼镜:

  1. 在轻松场景下,新旧技术表现差不多(就像20个同学打饭,用不用新技术都很快)
  2. 但一到人多的场景,虚拟线程就开始掉链子——错误率飙升到近30%!(相当于每3个同学就有1个打不到饭)

问题出在哪?
发现两个大坑:

  1. 连接池的套路不灵了以前食堂阿姨(HikariCP连接池)会记住常来的同学(线程),直接给预留的饭菜(连接)。但现在虚拟线程每次都是新面孔,阿姨每次都重新打菜,累得手忙脚乱。
  2. 同步代码像堵墙有些操作必须排队进行(比如只有一个微波炉热饭),虚拟线程遇到这种场景就会"定住不动",完全发挥不出优势。

Java24号称能解决问题?实测...
Java24更新说能解决"定住"的问题,但我们实测发现:

  • 食堂阿姨还是记不住人
  • 微波炉前照样排长队
  • 根本问题一点没解决!

给开发者的真心话
虚拟线程就像共享单车:✅ 适合短途出行(简单I/O操作)❌ 别指望它跑马拉松(复杂场景)⚠️ 用之前要检查车况(适配现有代码)

目前来看:

  • 普通网站用不用差别不大
  • 超高并发时可能翻车
  • 想用好得改造连接池这些"食堂设备"

关键要点:

  • 虚拟线程不一定在负载下执行得更好,特别是在HikariCP这样的公共基础设施下。
  • JEP 491在我们的测试中没有显著改变性能。
  • ThreadLocal的使用和连接池中的同步块似乎是真实的瓶颈。

我们现在正计划探索Agroal(Quarkus的Loom友好池)等替代方案,以及DB繁重场景之外的其他工作负载。


总结:新技术不是万能药,用之前得先做实验!就像你不能因为出了折叠屏手机,就盲目把全班同学的手机都换掉对吧?