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

JDK 21 并发编程 - 教程

文章目录

  • 前言
  • 一、虚拟线程(Virtual Threads):让 “多线程” 不再昂贵
  • 二、结构化并发(Structured Concurrency):让多任务协作 “有条理”
  • 三、虚拟线程 + 结构化并发:强强联合
  • 总结

前言

Java 的并发并发模型在 JDK 21 迎来了 “革命性升级”,核心是解决传统并发编程的两大痛点:线程资源昂贵导致的高并发瓶颈和多任务协作混乱导致的代码复杂。这两个问题,JDK 21 分别用 “虚拟线程” 和 “结构化并发” 给出了答案。


一、虚拟线程(Virtual Threads):让 “多线程” 不再昂贵

传统并发的痛点:线程是 “重量级资源”
传统 Java 线程(平台线程)直接对应操作系统线程,创建一个线程要占用 1MB 左右内存,且操作系统能同时运行的线程数量有限(通常几千个)。如果遇到高并发场景(比如 10 万用户同时访问接口),线程池会瞬间耗尽,导致请求排队甚至失败。

比如下面的代码,用线程池处理 10 万任务,会因线程不足变得很慢:

// 传统线程池(最多 1000 个平台线程)
ExecutorService executor = Executors.newFixedThreadPool(1000);
// 模拟 10 万次 I/O 操作(如数据库查询、网络请求)
for (int i = 0; i < 100000; i++) {
executor.submit(() -> {
// 模拟 I/O 等待(比如查数据库)
Thread.sleep(100); // 此时线程完全空闲,但仍占用资源
return null;
});
}

原因:10 万任务要排队等待 1000 个线程,大部分时间线程在 “空等” I/O 结果,却浪费着宝贵的系统资源。

虚拟线程的解决方案:轻量级线程,数量 “几乎无限”

虚拟线程是 JVM 管理的 “轻量级线程”,不直接绑定操作系统线程。一个平台线程可以 “承载” 成千上万个虚拟线程,且创建成本极低(内存仅几 KB)。

核心优势:当虚拟线程执行 I/O 操作(如 sleep、数据库查询)时,JVM 会 “暂时释放” 它占用的平台线程,让其他虚拟线程使用。等 I/O 完成后,再重新分配一个平台线程继续运行。

// 虚拟线程池(自动管理,数量无上限)
ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor();
// 同样处理 10 万次 I/O 操作
for (int i = 0; i < 100000; i++) {
executor.submit(() -> {
Thread.sleep(100); // 虚拟线程等待时,平台线程会被释放
return null;
});
}

效果:10 万任务几乎同时启动,无需排队,因为虚拟线程不占用宝贵的平台线程资源,I/O 等待时会 “让出” 资源给其他任务。
通俗理解

  • 平台线程 = 一辆满载的卡车,跑起来费油(资源),一次只能拉少量货物(任务)。
  • 虚拟线程 = 自行车队,轻便灵活, thousands of 辆自行车可以共享一条马路(平台线程),I/O 等待时还会主动下车让道。

二、结构化并发(Structured Concurrency):让多任务协作 “有条理”

传统并发的痛点:多任务 “各自为政”,容易出乱子

当一个任务需要拆分多个子任务并行执行时(比如接口需要同时调用 3 个微服务,再汇总结果),传统写法会有两个问题:
1.子任务失败了,其他子任务还在瞎跑,浪费资源;
2.需要手动处理异常和线程关闭,代码臃肿。

比如下面的代码,假设 fetchUser() 失败,fetchOrder() 和 fetchCart() 还会继续执行:

// 传统方式:三个子任务并行执行
ExecutorService executor = Executors.newFixedThreadPool(3);
Future<User> userFuture = executor.submit(() -> fetchUser());Future<Order> orderFuture = executor.submit(() -> fetchOrder());Future<Cart> cartFuture = executor.submit(() -> fetchCart());try {User user = userFuture.get(); // 等待用户信息Order order = orderFuture.get(); // 等待订单信息Cart cart = cartFuture.get(); // 等待购物车信息return new Result(user, order, cart);} catch (Exception e) {// 手动取消所有子任务(容易遗漏)userFuture.cancel(true);orderFuture.cancel(true);cartFuture.cancel(true);throw e;}

结构化并发的解决方案:子任务 “荣辱与共”
结构化并发将多个子任务视为一个 “整体”,用 StructuredTaskScope 管理:

  • 父任务等待所有子任务完成;
  • 任何一个子任务失败,自动取消其他子任务;
  • 无需手动关闭线程,自动释放资源。

案例:子任务失败自动取消其他任务

// 结构化并发:子任务绑定到一个“作用域”
try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {
// 启动三个子任务(fork = 分叉执行)
Future<User> userFuture = scope.fork(() -> fetchUser());Future<Order> orderFuture = scope.fork(() -> fetchOrder());Future<Cart> cartFuture = scope.fork(() -> fetchCart());scope.join(); // 等待所有子任务完成scope.throwIfFailed(); // 若有子任务失败,直接抛出异常// 所有任务成功,汇总结果return new Result(userFuture.result(),orderFuture.result(),cartFuture.result());}

效果:如果 fetchUser() 抛出异常,scope.join() 会发现失败,自动调用 shutdown() 取消 fetchOrder() 和 fetchCart(),避免资源浪费。

通俗理解

  • 传统并发 = 三个朋友各自去买奶茶,其中一个人没买到,另外两个人还在傻傻排队。
  • 结构化并发 = 三个人组队买奶茶,队长(父任务)说:“有人没买到,大家都别买了,赶紧回来!”

三、虚拟线程 + 结构化并发:强强联合

案例:高并发接口同时调用多个服务

// 处理用户请求的接口
public Result handleRequest() throws Exception {
// 1. 创建虚拟线程的结构化作用域
try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {
// 2. 用虚拟线程启动子任务(默认使用虚拟线程)
Future<User> userFuture = scope.fork(() -> fetchUser()); // 调用用户服务Future<Order> orderFuture = scope.fork(() -> fetchOrder()); // 调用订单服务Future<Cart> cartFuture = scope.fork(() -> fetchCart()); // 调用购物车服务// 3. 等待所有子任务完成,失败则取消其他任务scope.join();scope.throwIfFailed();// 4. 汇总结果return new Result(userFuture.result(),orderFuture.result(),cartFuture.result());}}

这个接口能轻松应对数万并发请求,因为:

  • 虚拟线程让每个子任务的创建成本几乎可以忽略;
  • 结构化并发确保任何子任务失败时,其他任务及时停止,不浪费资源。

总结

JDK 21 的并发模型升级,本质是让开发者 “少关心线程,多关注业务”:

  • 虚拟线程:解决 “线程不够用” 的问题,让高并发场景不再需要复杂的线程池调优;
  • 结构化并发:解决 “多任务协作乱” 的问题,让并发代码像同步代码一样直观。

对于日常开发,优先在 I/O 密集型场景(如 Web 接口、微服务调用)中使用这两个特性,能显著提升系统吞吐量并简化代码。

http://www.jsqmd.com/news/325432/

相关文章:

  • 2026年本地评价高的新初一补习冲刺班推荐榜单,新初一补课/新初一补课班/补习/新高一补课班,新初一补习机构推荐
  • 算法工程化十年演进
  • 清理空间
  • 车辆控制十年演进
  • pdf转word保留排版,常用免费工具TOP5推荐
  • 免费公众号SVG制作工具,新手用这2个排版素材学公众号排版还会难?推荐2个
  • MySQL页结构的庖丁解牛
  • 多智能体 KYC 系统实战:架构、组件与技术栈全解析
  • 寒假第一篇笔记
  • Claude Code:进入dash模式
  • 瑞昌市英语雅思培训机构推荐?2026权威测评出国雅思辅导机构口碑榜单
  • 【2022年KBS SCI1区TOP】基于强化学习的多模式协作多目标粒子群算法+多无人机路径规划文章解读
  • 2026年国际空运物流公司推荐盘点:中国市场五大服务商优势对比解析
  • 瑞昌市英语雅思培训机构推荐|2026权威测评出国雅思辅导机构口碑榜单
  • 2026年企业软著申请怎么办?从0到1的完整攻略来了
  • 上饶市英语雅思培训机构推荐;2026权威测评出国雅思辅导机构口碑榜单
  • 讲讲吴江中天化工环保措施到位情况,产能规模大适合哪些客户?
  • 瑞昌市英语雅思培训机构推荐,2026权威测评出国雅思辅导机构口碑榜单
  • Redis 集群
  • 哈尔滨代理记账品牌企业哪家靠谱
  • 2026年靠谱的工厂采光瓦品牌推荐,普世建材费用怎么算
  • 乐平市英语雅思培训机构推荐 ?2026权威测评出国雅思辅导机构口碑榜单
  • 瑞昌市英语雅思培训机构推荐:2026权威测评出国雅思辅导机构口碑榜单
  • 瑞昌市英语雅思培训机构推荐;2026权威测评出国雅思辅导机构口碑榜单
  • 选购建筑劳务资质代办服务,高效的远东建业靠谱不?
  • 乐平市英语雅思培训机构推荐:2026权威测评出国雅思辅导机构口碑榜单
  • 分析中企优帮的服务是否及时,企业服务公司哪家口碑好
  • 2026年齐齐哈尔专业的代理记账服务,高满意度公司排名
  • 乐平市英语雅思培训机构推荐|2026权威测评出国雅思辅导机构口碑榜单
  • 2026最新PyCharm安装和配置(详细步骤)