Java 中的虚拟线程
1. 是什么
Java中的虚拟线程(Virtual Threads)是在JDK 19中引入的一个新特性,它是一种轻量级的线程实现。虚拟线程旨在简化并发编程,提高应用程序的吞吐量,特别是在处理大量并发任务时。
2. 作用
- 提高并发性能:虚拟线程可以创建大量轻量级线程,减少系统资源消耗。
- 简化并发编程:使用虚拟线程可以用同步的方式编写异步代码,提高代码可读性。
- 提高系统吞吐量:特别是在I/O密集型应用中,可以显著提高系统的吞吐量。
3. 使用场景
- I/O密集型应用:如网络服务器、数据库操作、文件处理等。
- 微服务架构:处理大量并发请求的微服务。
- 任务调度系统:需要管理大量并发任务的系统。
- 爬虫应用:并发处理多个网页请求。
- 批处理应用:并行处理大量数据。
4. 和普通多线程对比
特性 | 虚拟线程 | 普通线程 |
---|---|---|
实现方式 | 由JVM管理,基于用户态线程 | 由操作系统管理,基于内核态线程 |
资源消耗 | 轻量级,可以创建大量(百万级) | 较重,通常限制在几千个 |
上下文切换 | 快速,在用户态完成 | 较慢,需要内核态切换 |
阻塞行为 | 不会阻塞底层系统线程 | 会阻塞系统线程 |
适用场景 | I/O密集型任务,高并发 | CPU密集型任务 |
内存占用 | 非常低 | 较高 |
创建和销毁开销 | 非常低 | 较高 |
调度方式 | 协作式调度 | 抢占式调度 |
支持的Java版本 | Java 19及以上 | 所有Java版本 |
与现有代码兼容性 | 可能需要适配 | 完全兼容 |
适合长时间运行的任务 | 不适合 | 适合 |
同步机制 | 支持,但应避免长时间同步 | 完全支持 |
中断机制 | 支持 | 支持 |
栈大小 | 动态增长,初始很小 | 固定大小,通常较大 |
与NIO的集成 | 原生支持 | 需要额外编程 |
5. 使用方式
创建单个虚拟线程
Thread.startVirtualThread(() -> {// 任务代码
});
使用ExecutorService创建虚拟线程
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {IntStream.range(0, 10_000).forEach(i -> {executor.submit(() -> {// 任务代码});});
}
try (ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor()) {List<CompletableFuture<Void>> futures = new ArrayList<>();for (int i = 0; i < 10000; i++) {int taskId = i;CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {// 执行异步任务System.out.println("Task " + taskId + " executed by " + Thread.currentThread());}, executor);futures.add(future);}// 等待所有任务完成CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();
}