Java 21 虚拟线程
一、虚拟线程作用
1. 资源高效:可创建数百万个虚拟线程而不会耗尽系统资源(传统线程通常限制在数千个)。
2. 简化并发模型:允许开发者用同步阻塞的代码风格(Thread.sleep()、I/O 等待)编写高并发应用,无需回调地狱或复杂异步 API。
3. 提升吞吐量:特别适合高并发 I/O 型应用(如 Web 服务、数据库访问),线程阻塞时自动释放载体线程,最大化 CPU 利用率。
4. 无缝兼容:与现有 java.lang.Thread API 兼容,无需重写代码。
二、代码示例
import java.util.concurrent.*;public class VirtualThreadDemo {public static void main(String[] args) throws InterruptedException {// 1. 创建虚拟线程执行任务Thread virtualThread = Thread.ofVirtual().start(() -> {System.out.println("Hello from virtual thread: " + Thread.currentThread().threadId());});virtualThread.join(); // 确保虚拟线程执行完成// 2. 添加时间测量和结果处理long startTime = System.currentTimeMillis();try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {// 使用Future收集结果(演示用100个任务)Future<?>[] futures = new Future[100];for (int i = 0; i < futures.length; i++) {final int taskId = i;futures[i] = executor.submit(() -> {try {// 模拟I/O操作Thread.sleep(10);return "Task-" + taskId + " (Thread: " + Thread.currentThread().threadId() + ")";} catch (InterruptedException e) {Thread.currentThread().interrupt();return "Task-" + taskId + " interrupted";}});}// 3. 获取并打印部分结果for (int i = 0; i < 5; i++) { // 仅打印前5个结果System.out.println("Result: " + futures[i].get());}// 4. 等待所有任务完成for (Future<?> future : futures) {future.get(); // 确保所有任务完成}} catch (ExecutionException e) {e.printStackTrace();}// 5. 打印执行时间System.out.println("Total time: " + (System.currentTimeMillis() - startTime) + " ms");}
}
三、与传统线程相比
特性 | 虚拟线程 | 传统平台线程 |
---|---|---|
资源占用 | ~ 1KB内存/线程 | ~ 1MB内存/线程 |
创建数量 | 百万级 | 数千(受OS限制) |
阻塞成本 | 近乎零开销(自动释放载体线程) | 高(OS上下文切换) |
调度器 | JVM管理 | 操作系统内核管理 |
适用场景 | 高并发I/O任务 | CPU密集型计算 |
堆栈存储位置 | Java堆内存 | OS内存 |
监控与调试 | 支持JFR和JStack | 传统工具支持 |