news 2026/4/29 16:46:20

Java 25 虚拟线程与结构化并发的结合:并发编程的黄金组合

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Java 25 虚拟线程与结构化并发的结合:并发编程的黄金组合

Java 25 虚拟线程与结构化并发的结合:并发编程的黄金组合

别叫我大神,叫我 Alex 就好。今天我们来聊聊 Java 25 中虚拟线程与结构化并发的结合,这是并发编程的黄金组合。

一、虚拟线程与结构化并发的关系

虚拟线程和结构化并发是 Java 近年来引入的两个革命性特性,它们解决了不同但相关的问题:

  • 虚拟线程:解决了传统线程的资源占用高、创建成本高的问题,让我们可以轻松创建数百万个线程
  • 结构化并发:解决了并发任务的管理问题,让我们可以更清晰地管理任务的生命周期

当这两个特性结合使用时,它们形成了一个强大的组合,让并发编程变得更加简单、优雅和高效。

二、基本用法

1. 在结构化并发中使用虚拟线程

public class VirtualThreadsWithStructuredConcurrency { public User getUserWithDetails(String userId) { try (var scope = new StructuredTaskScope.ShutdownOnFailure()) { // 使用虚拟线程执行任务 Future<User> userFuture = scope.fork(() -> { return userService.getUser(userId); }); Future<UserProfile> profileFuture = scope.fork(() -> { return profileService.getUserProfile(userId); }); Future<List<Order>> ordersFuture = scope.fork(() -> { return orderService.getUserOrders(userId); }); scope.join(); scope.throwIfFailed(); User user = userFuture.resultNow(); user.setProfile(profileFuture.resultNow()); user.setOrders(ordersFuture.resultNow()); return user; } } }

2. 自定义虚拟线程执行器

public class VirtualThreadExecutor { private static final Executor VIRTUAL_THREAD_EXECUTOR = Executors.newVirtualThreadPerTaskExecutor(); public static <T> T executeWithVirtualThread(Supplier<T> task) { try (var scope = new StructuredTaskScope.ShutdownOnFailure()) { Future<T> future = scope.fork(task::get); scope.join(); scope.throwIfFailed(); return future.resultNow(); } } public static void executeWithVirtualThread(Runnable task) { VIRTUAL_THREAD_EXECUTOR.execute(task); } }

三、高级用法

1. 嵌套结构化并发

public class NestedStructuredConcurrency { public OrderDetails getOrderDetails(String orderId) { try (var scope = new StructuredTaskScope.ShutdownOnFailure()) { // 第一层:获取订单基本信息 Future<Order> orderFuture = scope.fork(() -> { return orderService.getOrder(orderId); }); // 第二层:获取订单相关信息 Future<OrderRelatedInfo> relatedInfoFuture = scope.fork(() -> { try (var innerScope = new StructuredTaskScope.ShutdownOnFailure()) { Future<List<OrderItem>> itemsFuture = innerScope.fork(() -> { return orderItemService.getOrderItems(orderId); }); Future<Payment> paymentFuture = innerScope.fork(() -> { return paymentService.getOrderPayment(orderId); }); Future<Logistics> logisticsFuture = innerScope.fork(() -> { return logisticsService.getOrderLogistics(orderId); }); innerScope.join(); innerScope.throwIfFailed(); return new OrderRelatedInfo( itemsFuture.resultNow(), paymentFuture.resultNow(), logisticsFuture.resultNow() ); } }); scope.join(); scope.throwIfFailed(); return new OrderDetails( orderFuture.resultNow(), relatedInfoFuture.resultNow() ); } } }

2. 超时处理

public class TimeoutHandling { public User getUserWithTimeout(String userId, Duration timeout) { try (var scope = new StructuredTaskScope.ShutdownOnFailure()) { Future<User> userFuture = scope.fork(() -> { return userService.getUser(userId); }); // 等待结果或超时 scope.join(timeout); if (scope.isCompletedSuccessfully()) { return userFuture.resultNow(); } else { throw new TimeoutException("Operation timed out"); } } } }

四、性能优化

1. 批量操作

public class BatchProcessing { public List<User> getUsersBatch(List<String> userIds) { try (var scope = new StructuredTaskScope.ShutdownOnFailure()) { List<Future<User>> futures = userIds.stream() .map(userId -> scope.fork(() -> userService.getUser(userId))) .collect(Collectors.toList()); scope.join(); scope.throwIfFailed(); return futures.stream() .map(Future::resultNow) .collect(Collectors.toList()); } } }

2. 背压控制

public class BackpressureControl { public List<User> getUsersWithBackpressure(List<String> userIds, int batchSize) { List<User> results = new ArrayList<>(); // 分批处理,控制并发度 for (int i = 0; i < userIds.size(); i += batchSize) { int end = Math.min(i + batchSize, userIds.size()); List<String> batchIds = userIds.subList(i, end); try (var scope = new StructuredTaskScope.ShutdownOnFailure()) { List<Future<User>> futures = batchIds.stream() .map(userId -> scope.fork(() -> userService.getUser(userId))) .collect(Collectors.toList()); scope.join(); scope.throwIfFailed(); futures.stream() .map(Future::resultNow) .forEach(results::add); } } return results; } }

五、实践案例:电商平台订单处理

场景描述

电商平台需要处理订单创建、库存检查、支付处理等多个并发操作。

实现方案

@Service public class OrderProcessingService { private final InventoryService inventoryService; private final PaymentService paymentService; private final OrderRepository orderRepository; private final EventPublisher eventPublisher; // 构造函数省略 public Order createOrder(CreateOrderRequest request) { try (var scope = new StructuredTaskScope.ShutdownOnFailure()) { // 1. 检查库存 Future<Boolean> stockCheckFuture = scope.fork(() -> { return inventoryService.checkStock( request.getProductId(), request.getQuantity()); }); // 2. 验证用户 Future<User> userFuture = scope.fork(() -> { return userService.getUser(request.getUserId()); }); // 3. 计算价格 Future<BigDecimal> priceFuture = scope.fork(() -> { return pricingService.calculatePrice( request.getProductId(), request.getQuantity()); }); scope.join(); scope.throwIfFailed(); // 检查库存 if (!stockCheckFuture.resultNow()) { throw new InsufficientStockException("Not enough stock"); } // 创建订单 Order order = Order.builder() .userId(request.getUserId()) .productId(request.getProductId()) .quantity(request.getQuantity()) .totalPrice(priceFuture.resultNow()) .status(OrderStatus.CREATED) .build(); // 保存订单 order = orderRepository.save(order); // 4. 处理支付 scope.fork(() -> { PaymentRequest paymentRequest = PaymentRequest.builder() .orderId(order.getId()) .userId(request.getUserId()) .amount(priceFuture.resultNow()) .build(); return paymentService.processPayment(paymentRequest); }); // 5. 扣减库存 scope.fork(() -> { return inventoryService.decreaseStock( request.getProductId(), request.getQuantity()); }); scope.join(); scope.throwIfFailed(); // 发布订单创建事件 eventPublisher.publishEvent(new OrderCreatedEvent(order)); return order; } } }

六、常见问题与解决方案

1. 异常处理

public class ExceptionHandling { public User getUserWithErrorHandling(String userId) { try (var scope = new StructuredTaskScope.ShutdownOnFailure()) { Future<User> userFuture = scope.fork(() -> { try { return userService.getUser(userId); } catch (UserNotFoundException e) { // 处理特定异常 logger.warn("User not found: {}", userId); return new User(userId, "Unknown", "unknown@example.com"); } }); scope.join(); try { scope.throwIfFailed(); } catch (Exception e) { // 处理其他异常 logger.error("Failed to get user: {}", e.getMessage()); return new User(userId, "Error", "error@example.com"); } return userFuture.resultNow(); } } }

2. 资源管理

public class ResourceManagement { public List<User> getUsersWithResourceManagement(List<String> userIds) { try (var scope = new StructuredTaskScope.ShutdownOnFailure(); var connection = dataSource.getConnection()) { List<Future<User>> futures = userIds.stream() .map(userId -> scope.fork(() -> { try (var statement = connection.prepareStatement( "SELECT * FROM users WHERE id = ?")) { statement.setString(1, userId); try (var resultSet = statement.executeQuery()) { if (resultSet.next()) { return new User( resultSet.getString("id"), resultSet.getString("name"), resultSet.getString("email") ); } else { throw new UserNotFoundException(userId); } } } })) .collect(Collectors.toList()); scope.join(); scope.throwIfFailed(); return futures.stream() .map(Future::resultNow) .collect(Collectors.toList()); } } }

七、总结与建议

虚拟线程与结构化并发的结合,为 Java 并发编程带来了革命性的变化。它们不仅让代码更加清晰、易读,还提高了系统的性能和可靠性。

这其实可以更优雅一点,建议大家在以下场景优先考虑使用虚拟线程与结构化并发的组合:

  1. IO 密集型任务:如数据库查询、HTTP 调用等
  2. 批量处理:需要并行处理多个独立任务
  3. 复杂业务流程:涉及多个步骤的业务流程
  4. 高并发场景:需要处理大量并发请求

别叫我大神,叫我 Alex 就好。希望这篇文章能帮助你更好地理解和使用 Java 25 的虚拟线程与结构化并发。欢迎在评论区分享你的使用经验!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/11 5:40:06

零代码玩转HY-Motion 1.0:在Gradio可视化界面中实时预览文字转动作

零代码玩转HY-Motion 1.0&#xff1a;在Gradio可视化界面中实时预览文字转动作 1. 从文字到动作&#xff1a;一键启动的魔法体验 想象一下&#xff0c;当你输入"一个人从椅子上站起来&#xff0c;转身180度后挥手致意"&#xff0c;屏幕上立刻出现一个3D人形骨架精准…

作者头像 李华
网站建设 2026/4/12 8:54:48

CC Switch搭建到vscode

适配 win 和 Ubuntu 下的环境cc-switch下载 通过网盘分享的文件&#xff1a;CC-Switch 链接: https://pan.baidu.com/s/1YthfhQSnk3S4RvajG6Ax8Q?pwd8rtr 提取码: 8rtrwin 使用 CC-Switch-v3.12.3-Windows.msiUbuntu 22 以下使用 CC-Switch-cli-linux-x64-musl.tar.gzUbuntu 2…

作者头像 李华
网站建设 2026/4/11 5:37:26

别再只画静态图了!用Qt QChart实现可交互波形图的5个高级技巧

别再只画静态图了&#xff01;用Qt QChart实现可交互波形图的5个高级技巧 在数据可视化领域&#xff0c;静态图表已经无法满足现代应用对用户体验的严苛要求。想象一下&#xff0c;当用户面对一个温度监测系统时&#xff0c;如果只能被动地观看一条固定不变的曲线&#xff0c;而…

作者头像 李华
网站建设 2026/4/11 5:32:13

Nunchaku-flux-1-dev风格迁移效果:将实拍照片转化为水墨画风

Nunchaku-flux-1-dev风格迁移效果&#xff1a;将实拍照片转化为水墨画风 最近试用了Nunchaku-flux-1-dev模型来做风格迁移&#xff0c;特别是尝试了把普通照片变成水墨画的效果&#xff0c;结果还挺让人惊喜的。这玩意儿不是简单加个滤镜&#xff0c;而是真的能理解“水墨画”…

作者头像 李华
网站建设 2026/4/11 5:30:10

【运维实战】二层环路检测与MAC漂移的精准定位技巧

1. 二层环路与MAC漂移&#xff1a;运维必须警惕的"网络杀手" 刚接手公司核心网络那会儿&#xff0c;我最怕的就是半夜接到告警电话说全网卡顿。有一次凌晨3点整个办公区网络瘫痪&#xff0c;显示器上全是流量风暴告警&#xff0c;那次经历让我深刻认识到二层环路和MA…

作者头像 李华