系列主题:Java Virtual Threads(虚拟线程)教程:从零上手到实战优化
一、为什么要学习 Virtual Threads?(为什么它成为热点)
Java 在 JDK 19 引入 Virtual Threads(预览)后,到 JDK 21 成为正式特性,是 Java 最大的变革之一。
它的目标非常简单:
让 Java 的并发变得更轻,更简单,更快,让每个并发任务都能拥有自己的线程。
传统 Java 并发难点:
而虚拟线程的出现,让 Java 拥有了协程级别的能力:
Virtual Thread 的优势
线程超轻量:几十 KB,百万级线程不是问题
阻塞等同于异步 I/O:写同步风格就能跑出异步性能
基本不需要线程池调优
代码可读性极佳,能回归传统同步写法
JDK 官方维护,性能、稳定性、生态直接受益
一句话总结:虚拟线程让 Java 写法变简单,性能变更强。
二、Virtual Thread 到底是什么?(核心概念)
Java 传统线程是绑定在 OS 级线程上的:
Java Thread = 内核线程
虚拟线程则是:
Virtual Thread = 由 JVM 管理的“用户态线程”
从模型上来看:
┌──────────────────────────┐
│ 虚拟线程(几万~百万) │
└──────────────────────────┘
↓ 调度
┌──────────────────────────┐
│ 少量平台线程(几十个) │
└──────────────────────────┘
↓
┌──────────────────────────┐
│ CPU 核心 │
└──────────────────────────┘
虚拟线程不是线程池,它是百万级并发的“线程模型革命”。
三、快速体验:创建你的第一个虚拟线程
虚拟线程使用方式非常简单。
方式1:Thread.ofVirtual().start()
public class HelloVirtualThread {
public static void main(String[] args) {
Thread thread = Thread.ofVirtual().start(() -> {
System.out.println("Hello from Virtual Thread!");
});
}
}
方式2:使用 Executors(JDK21 推荐)
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
executor.submit(() -> {
System.out.println("Running in Virtual Thread");
});
}
每个任务一个虚拟线程,不再需要复杂的线程池调优。
四、虚拟线程的核心行为:阻塞≠慢
传统线程中,阻塞调用是性能杀手:
Thread.sleep(2000); // 真的占用线程 2 秒
在虚拟线程中:
Thread.sleep(2000); // 虚拟线程挂起,不占用平台线程
虚拟线程的阻塞是“廉价”的,因为阻塞时:
虚拟线程会 自动让出平台线程
不占用 CPU 或 OS Thread 资源
这意味着你可以回到同步代码写法,而获得异步的性能。
五、对比:10000 个线程的创建成本
传统线程(Platform Thread)版本
public class PlatformThreadTest {
public static void main(String[] args) {
for (int i = 0; i < 10000; i++) {
new Thread(() -> {
try { Thread.sleep(1000); } catch (Exception ignored) {}
}).start();
}
}
}
结果:
❌ 非常慢
❌ 可能 OOM
❌ 占用大量内存
虚拟线程版本
public class VirtualThreadTest {
public static void main(String[] args) {
for (int i = 0; i < 10000; i++) {
Thread.ofVirtual().start(() -> {
try { Thread.sleep(1000); } catch (Exception ignored) {}
});
}
}
}
结果:
✔ 几毫秒创建完毕
✔ 内存占用很低
✔ 轻松扩展到 100 万线程
六、虚拟线程适用的场景(非常重要)
虚拟线程并不能提高 CPU 性能,但可以极大提高 I/O 密集型系统吞吐量。
七、注意事项:什么时候不要使用虚拟线程?
1. CPU 密集型计算
虚拟线程不会让 CPU magically 变强。
2. 阻塞式同步集合(如 ReentrantLock)过多
虽然能用,但会降低性能。
推荐使用 无锁结构、CAS 或 Concurrent 系列集合。
3. 自定义线程池(大多数情况不需要)
如业务复杂但线程池配置反而成为累赘。
八、总结:第 1 篇你应该学会了什么?
通过本篇,你应该已经明确:
✔ Virtual Threads 的出现是因为传统线程过重
✔ 它是一种“用户态线程”,由 JVM 管理,非常轻量
✔ 适用于 I/O 密集型业务,能创建百万线程
✔ 使用方式极其简单:Thread.ofVirtual() 或 Executors
✔ 阻塞是廉价的,可像写同步代码一样获得异步性能
✔ 下一篇将正式进入实战:HTTP、数据库、RPC 的虚拟线程优化
下一篇预告(第 2 篇)
《使用 Virtual Threads 重构传统同步代码:HTTP/DB/RPC 实战提升》
内容将包含:
使用虚拟线程优化 HTTP 客户端(同步写法性能媲美异步)
优化数据库查询的并发吞吐
重构传统线程池代码
对虚拟线程调度的深入讲解
默认评论
Halo系统提供的评论