当前位置: 首页 > ds >正文

讲一件Java虚拟线程

最近在思考一个问题,Java的虚拟线程有什么用

传统线程池在应对高并发请求时,如同让一群壮汉挤在狭窄的走廊里——资源浪费严重,效率低下。

痛点:线程池的阻塞瓶颈

在典型的Web服务中,我们常使用线程池处理请求。但当遇到大量I/O操作(如数据库查询、外部API调用)时,线程会被阻塞,导致资源浪费:

// 传统线程池处理请求
ExecutorService executor = Executors.newFixedThreadPool(200);void handleRequest(Request request) {executor.execute(() -> {// 线程在此阻塞等待数据库响应Result result = queryDatabase(request); processResult(result);});
}

当并发量达到数千时,线程池会:

  1. 耗尽线程导致新请求排队
  2. 消耗大量内存(每个线程约1MB栈空间)
  3. 频繁线程上下文切换增加CPU开销

虚拟线程:轻量级并发解决方案

Java 19引入的虚拟线程(Virtual Threads)通过​​M:N调度模型​​解决此问题:

// 使用虚拟线程处理请求
void handleRequestVirtual(Request request) {Thread.startVirtualThread(() -> {Result result = queryDatabase(request);processResult(result);});
}
核心优势对比:
​特性​​平台线程​​虚拟线程​
内存开销~1MB/线程~几百字节/线程
创建成本毫秒级微秒级
阻塞代价高(OS线程阻塞)低(仅挂载JVM栈)
最大数量数千数百万

实战:吞吐量提升10倍

测试一个简单的HTTP服务(Spring Boot 3.2+):

// 虚拟线程配置
@Bean
public TomcatProtocolHandlerCustomizer<?> protocolHandlerVirtualThreads() {return protocolHandler -> protocolHandler.setExecutor(Executors.newVirtualThreadPerTaskExecutor());
}// 模拟数据库阻塞操作
@GetMapping("/data")
public String fetchData() throws InterruptedException {Thread.sleep(1000); // 模拟I/O阻塞return "Data fetched";
}

​压测结果(JMeter 5000并发)​​:

  • 传统线程池(200线程):吞吐量 180/sec,95%响应时间 >5s
  • 虚拟线程:吞吐量 1950/sec,95%响应时间 1.2s

避坑指南:虚拟线程的正确使用

  1. ​避免同步代码块​

    synchronized(lock) {// 会阻塞载体线程doWork(); 
    }

    改用ReentrantLock

    lock.lock();
    try { doWork(); } 
    finally { lock.unlock(); }
  2. ​线程局部变量慎用​

    // 可能导致内存泄漏
    ThreadLocal<User> userHolder = new ThreadLocal<>();

    改用ScopedValue(Java 20+)

  3. ​CPU密集型任务需分离​

    // CPU密集型任务应使用平台线程
    CompletableFuture.supplyAsync(this::heavyComputation, Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()));

监控与调试

虚拟线程需要新的监控方式:

# 查看虚拟线程状态
jcmd <pid> Thread.dump_to_file -format=json vthreads.json# 异步分析工具
jfr configure --threaddump

架构影响与未来

虚拟线程正在改变Java生态:

  1. Web服务器(Tomcat/Jetty)默认支持虚拟线程
  2. 响应式框架(如WebFlux)与虚拟线程融合
  3. 数据库连接池自动适配(HikariCP 5.0+)

​关键洞察​​:虚拟线程不是万能药,而是将I/O密集型应用的复杂度从"分布式系统级别"降回"单机级别"的工具。它让编写高并发代码回归到直观的阻塞式编程模型,同时保持非阻塞的性能优势。

http://www.xdnf.cn/news/13613.html

相关文章:

  • 小白理财 - 入门第一课
  • 扁平风格职场商务通用PPT模版分享
  • AI支持下的-ArcGIS数据处理、空间分析、可视化及多案例综合应用
  • Java多线程实现之同步方法详解
  • Win10重装系统 (重生篇:我在华强修电脑)
  • 用python玩转大语言模型——从 RNN 到文本生成大语言模型的奇幻之旅
  • SpringBoot学习day2-前后端的交互搭建以及跨域问题、拦截过滤器问题的解决
  • 理解系统交互:UML时序图
  • 驭码CodeRider 2.0 产品体验:在VSCode安装并创建一个雷电小游戏
  • Django项目QQ授权登录报错:redirect uri is illegal(100010) 解决方法
  • 深度学习小项目合集之音频语音识别
  • docker-compose搭建eureka-server和zipkin
  • ubuntu 安装 JDK8
  • 安信可(云知声蜂鸟US516P6)SDK开发学习---log日志打印子系统模块
  • 云原生安全实践:CI/CD流水线集成DAST工具
  • 【PostgreSQL系列】PostgreSQL WAL 目录配置
  • 力扣HOT100之贪心算法:45. 跳跃游戏 II
  • 零基础设计模式——行为型模式 - 备忘录模式
  • 前端实现ios26最新液态玻璃效果!
  • Leetcode-11 2 的幂
  • 前端实战:用 HTML+JS 打造可拖动图像对比滑块,提升视觉交互体
  • Reactive-Resume:重构你的简历编写体验
  • window 显示驱动开发-如何查询视频处理功能(六)
  • (LeetCode 动态规划(基础版) )337. 打家劫舍 III (深度优先搜索dfs)
  • 智慧医疗能源事业线深度画像分析(下)
  • window 显示驱动开发-创建视频处理设备
  • android studio底部导航栏
  • Windows 上安装 devsidecar 后,使用 WSL ubuntu ssl 报错
  • redisson锁的可重入、可重试、超时续约原理详解
  • npm包 本地测试流程