找回密码
 立即注册
首页 业界区 安全 Java虚拟线程实战:Project Loom让并发编程更简单 ...

Java虚拟线程实战:Project Loom让并发编程更简单

跑两獗 昨天 21:56
前言

Java 21 正式引入虚拟线程(Virtual Threads),这是 Project Loom 的核心成果。虚拟线程让 Java 并发编程从"难"变"简",彻底改变了高并发应用的开发方式。本文带你全面掌握虚拟线程。
一、虚拟线程 vs 平台线程


  • 平台线程:对应操作系统线程,创建成本高(约1MB栈内存),数量受限
  • 虚拟线程:JVM 管理的轻量级线程,创建成本极低(约几KB),可创建数百万个
  1. // 平台线程:创建100万个会OOM
  2. Thread platformThread = new Thread(() -> doWork());
  3. platformThread.start();
  4. // 虚拟线程:创建100万个轻松搞定
  5. Thread virtualThread = Thread.ofVirtual().start(() -> doWork());
复制代码
二、创建虚拟线程的四种方式
  1. // 方式1:Thread.ofVirtual()
  2. Thread vt1 = Thread.ofVirtual().name("vt-1").start(() -> {
  3.     System.out.println("Virtual thread: " + Thread.currentThread());
  4. });
  5. // 方式2:Thread.startVirtualThread()
  6. Thread vt2 = Thread.startVirtualThread(() -> {
  7.     System.out.println("Running in virtual thread");
  8. });
  9. // 方式3:虚拟线程 ExecutorService
  10. try (ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor()) {
  11.     executor.submit(() -> processRequest());
  12.     executor.submit(() -> processRequest());
  13. }
  14. // 方式4:ThreadFactory
  15. ThreadFactory factory = Thread.ofVirtual().factory();
  16. Thread vt4 = factory.newThread(() -> doWork());
  17. vt4.start();
复制代码
三、实战:高并发 HTTP 请求处理
  1. // 传统方式:线程池,受限于线程数
  2. ExecutorService threadPool = Executors.newFixedThreadPool(200);
  3. // 虚拟线程方式:每个请求一个虚拟线程
  4. @RestController
  5. public class UserController {
  6.     @GetMapping("/users/{id}")
  7.     public User getUser(@PathVariable Long id) {
  8.         // 虚拟线程会在 I/O 阻塞时自动挂起,释放载体线程
  9.         return userService.findById(id);  // 数据库查询
  10.     }
  11. }
  12. // Spring Boot 3.2+ 开启虚拟线程
  13. // application.yml
  14. // spring:
  15. //   threads:
  16. //     virtual:
  17. //       enabled: true
复制代码
四、性能对比测试
  1. public class PerformanceTest {
  2.     // 模拟 I/O 密集型任务
  3.     static void ioTask() throws InterruptedException {
  4.         Thread.sleep(100);  // 模拟数据库查询
  5.     }
  6.     public static void main(String[] args) throws Exception {
  7.         int taskCount = 10_000;
  8.         // 平台线程池
  9.         long start1 = System.currentTimeMillis();
  10.         try (ExecutorService pool = Executors.newFixedThreadPool(200)) {
  11.             List<Future<?>> futures = new ArrayList<>();
  12.             for (int i = 0; i < taskCount; i++) {
  13.                 futures.add(pool.submit(() -> { ioTask(); return null; }));
  14.             }
  15.             for (Future<?> f : futures) f.get();
  16.         }
  17.         System.out.println("Platform threads: " + (System.currentTimeMillis() - start1) + "ms");
  18.         // 输出约:5200ms
  19.         // 虚拟线程
  20.         long start2 = System.currentTimeMillis();
  21.         try (ExecutorService vExecutor = Executors.newVirtualThreadPerTaskExecutor()) {
  22.             List<Future<?>> futures = new ArrayList<>();
  23.             for (int i = 0; i < taskCount; i++) {
  24.                 futures.add(vExecutor.submit(() -> { ioTask(); return null; }));
  25.             }
  26.             for (Future<?> f : futures) f.get();
  27.         }
  28.         System.out.println("Virtual threads: " + (System.currentTimeMillis() - start2) + "ms");
  29.         // 输出约:120ms,提升40倍!
  30.     }
  31. }
复制代码
五、注意事项


  • 避免 synchronized 块:会导致虚拟线程固定(pinning),改用 ReentrantLock
  • 不适合 CPU 密集型任务:虚拟线程优势在 I/O 密集型场景
  • ThreadLocal 谨慎使用:大量虚拟线程时内存占用可能增加
  1. // 错误:synchronized 导致 pinning
  2. synchronized (lock) {
  3.     Thread.sleep(100);  // 虚拟线程被固定,无法挂起
  4. }
  5. // 正确:使用 ReentrantLock
  6. ReentrantLock lock = new ReentrantLock();
  7. lock.lock();
  8. try {
  9.     Thread.sleep(100);  // 虚拟线程可以正常挂起
  10. } finally {
  11.     lock.unlock();
  12. }
复制代码
总结

虚拟线程是 Java 并发编程的重大突破,特别适合 I/O 密集型的微服务场景。升级到 Java 21 + Spring Boot 3.2,一行配置即可享受虚拟线程带来的性能提升。

觉得有帮助请点赞收藏!有问题欢迎评论区交流
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

相关推荐

您需要登录后才可以回帖 登录 | 立即注册