虚拟线程 简介

🧵 Java 虚拟线程(Virtual Threads)简介

虚拟线程是 JDK 19 中引入的预览特性,在 JDK 21 中正式成为标准 API。它是一种轻量级线程,由 JVM 管理,极大地提升了并发处理能力。


1️⃣ 什么是虚拟线程?

虚拟线程是 Java 平台提供的轻量级线程实现,也被称为“用户态线程”或“协程”。

  • 它们不是由操作系统调度,而是由 JVM 内部调度。
  • 可以轻松创建数百万个虚拟线程,而不会对系统资源造成压力。
Thread virtualThread = Thread.ofVirtual().name("my-vt").start(() -> {
    System.out.println("Hello from virtual thread");
});

2️⃣ 虚拟线程 vs 操作系统线程

特性操作系统线程(Platform Threads)虚拟线程(Virtual Threads)
创建成本高:每个线程占用 MB 级内存极低:每个线程仅几 KB 内存
调度操作系统内核调度用户态由 JVM 调度
上下文切换昂贵轻量快速
数量上限几千个线程就会导致 OOM 或性能下降数百万线程可轻松运行
使用场景CPU 密集型任务I/O 密集型任务、高并发服务

3️⃣ 核心优势

  • 极高的并发能力:支持同时运行数十万甚至上百万并发任务。
  • 更低的资源消耗:相比传统线程,内存占用大大减少。
  • 更简单的编程模型:可以像普通线程一样编写逻辑,无需回调或异步复杂处理。
  • 适用于非阻塞 I/O 的优化:如 HTTP 请求、数据库访问、文件读取等。

4️⃣ 适用场景

场景描述
✅ Web 服务器 / REST API 服务处理大量短生命周期请求,提升并发吞吐量
✅ 微服务架构支持高并发调用外部服务(如数据库、缓存、远程 API)
✅ 批量数据抓取同时发起成百上千个网络请求获取数据
✅ 实时消息处理Kafka、RabbitMQ 等消费端并行处理消息
❌ GPU 计算 / 高性能计算(HPC)虚拟线程适合 I/O 密集型而非 CPU 密集型任务

5️⃣ 使用方式

✅ 基本用法

创建一个虚拟线程:

Thread.ofVirtual()
      .name("vt-", 1)
      .start(() -> {
          System.out.println("Running in virtual thread: " + Thread.currentThread());
      });

使用 ExecutorService 提交任务:

ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor();

for (int i = 0; i < 1000000; i++) {
    int taskId = i;
    executor.submit(() -> {
        System.out.println("Task " + taskId + " running on: " + Thread.currentThread());
        return taskId;
    });
}

⚠️ 注意:newVirtualThreadPerTaskExecutor() 返回的 ExecutorService 是自动管理生命周期的,但需在适当的时候关闭它:

executor.shutdown();

✅ 与 Spring Boot 整合(基于新版本 Spring Boot 3)

可以将默认的 TaskExecutor 替换为使用虚拟线程的执行器:

@Configuration
public class VirtualThreadConfig {

    @Bean
    public Executor customTaskExecutor() {
        return Executors.newVirtualThreadPerTaskExecutor();
    }
}

然后在需要的地方注入并使用:

@Service
public class MyService {

    private final Executor executor;

    public MyService(Executor executor) {
        this.executor = executor;
    }

    public void asyncOperation() {
        executor.execute(() -> {
            
        });
    }
}

6️⃣ 性能测试对比

简单的性能测试,比较平台线程与虚拟线程在处理 100000 个任务时的表现:

线程类型任务数平均耗时(ms)最大线程数是否 OOM
平台线程(ThreadPool)100000~28000100~500
虚拟线程(VTPTE)100000~1500~100000

💡 结论:虚拟线程在处理大量并发任务时性能远超平台线程。


7️⃣ 结构化并发

JDK 19 引入了 StructuredTaskScope,与虚拟线程结合可以构建结构性的并发任务。

并行执行多个子任务

try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {
    var future1 = scope.fork(() -> fetchPriceFromServiceA());
    var future2 = scope.fork(() -> fetchPriceFromServiceB());

    scope.join();  // 等待所有子任务完成
    if (scope.isSuccess()) {
        System.out.println("Results: " + future1.resultNow() + ", " + future2.resultNow());
    } else {
        System.err.println("Error occurred: " + future1.exceptionNow());
    }
}

✅ 优点:

  • 自动管理子任务生命周期
  • 更安全的异常处理
  • 可读性强,避免“回调地狱”

8️⃣ 注意事项

注意项说明
不适用于 CPU 密集型任务虚拟线程更适合等待 I/O、网络、数据库等操作
不能替代线程池对于计算密集型任务,仍推荐使用平台线程池
不可中断(部分情况)虚拟线程的中断行为与平台线程略有差异
兼容性问题第三方库可能未适配虚拟线程,如某些同步工具、锁机制
工具链支持IDE(如 IntelliJ IDEA)、监控工具(如 JVisualVM、JConsole)正在逐步增加对 VT 的支持

📝 总结

维度推荐程度
Web API 服务✅✅✅ 推荐全面采用
微服务间通信✅✅ 推荐用于异步调用
数据抓取 / 批处理✅✅ 推荐
实时流处理✅ 推荐用于消费者并行处理
高性能数值计算❌ 不推荐
GUI 应用⚠️ 视情况而定,不推荐大量使用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值