当前位置:首页 > 科技  > 软件

CompletableFuture:Java 8 中的异步编程利器

来源: 责编: 时间:2024-04-19 09:26:23 213观看
导读在现代软件开发中,异步编程已成为提升系统性能、响应能力和可扩展性的关键手段。Java 8 引入了 CompletableFuture 类,为 Java 平台带来了强大的异步编程能力。本篇文章将带你认识这个异步编程神器:CompletableFuture。

在现代软件开发中,异步编程已成为提升系统性能、响应能力和可扩展性的关键手段。Java 8 引入了 CompletableFuture 类,为 Java 平台带来了强大的异步编程能力。e5B28资讯网——每日最新资讯28at.com

本篇文章将带你认识这个异步编程神器:CompletableFuture。e5B28资讯网——每日最新资讯28at.com

什么是 CompletableFuture

CompletableFuture 是 Java 8 引入的 java.util.concurrent 包下的一个类,它代表一个异步计算的结果,可以是已完成、正在进行或尚未开始。CompletableFuture 提供了一种灵活、类型安全的方式来表达异步操作的生命周期,包括创建、组合、处理结果以及处理异常。其设计灵感来源于函数式编程中的 Promises/Futures 模式,旨在简化异步编程模型,提高代码的可读性和可维护性。e5B28资讯网——每日最新资讯28at.com

CompletableFuture 的核心功能

1. 创建 CompletableFuture

a. completedFuture(T value)

completedFuture(T value) 是一个静态工厂方法,用于创建一个已经处于完成状态且包含给定结果值的 CompletableFuture。这适用于预先计算好的结果或常量值,使得其他组件可以以异步形式消费。e5B28资讯网——每日最新资讯28at.com

b. supplyAsync(Supplier<U> supplier, Executor executor)

supplyAsync() 方法接受一个 Supplier 函数和一个可选的 Executor,异步执行 supplier.get(),并将结果封装到一个新的 CompletableFuture 中。计算在 Executor 管理的线程中进行,不阻塞当前线程。e5B28资讯网——每日最新资讯28at.com

c. runAsync(Runnable runnable, Executor executor)

类似于 supplyAsync(),runAsync() 接受一个 Runnable 任务和一个 Executor,异步执行任务。由于 Runnable 没有返回值,runAsync() 返回的 CompletableFuture 完成时没有结果。e5B28资讯网——每日最新资讯28at.com

2. 组合 CompletableFuture

a. thenApply(Function<? super T,? extends U> fn)

在当前 CompletableFuture 完成后,应用给定的 Function 处理结果,并返回一个新的 CompletableFuture,其结果为 Function 应用后的值。e5B28资讯网——每日最新资讯28at.com

b. thenAccept(Consumer<? super T> action)

当当前 CompletableFuture 完成后,执行给定的 Consumer 消费结果。由于 Consumer 没有返回值,返回的 CompletableFuture 完成时没有结果。e5B28资讯网——每日最新资讯28at.com

c. thenCombine(CompletionStage<? extends U> other, BiFunction<? super T,? super U,? extends V> fn)

当当前 CompletableFuture 与另一个 CompletionStage(如另一个 CompletableFuture)都完成时,应用给定的 BiFunction 合并两个结果,并返回一个新的 CompletableFuture。e5B28资讯网——每日最新资讯28at.com

3. 异常处理

a. exceptionally(Function<Throwable,? extends T> fn)

当当前 CompletableFuture 因异常而未能正常完成时,应用给定的 Function 处理异常,并返回一个新的 CompletableFuture,其结果为 Function 应用后的值。e5B28资讯网——每日最新资讯28at.com

b. handle(BiFunction<? super T, Throwable, ? extends U> fn)

无论当前 CompletableFuture 正常完成还是因异常未能完成,都会应用给定的 BiFunction 处理结果或异常,并返回一个新的 CompletableFuture。e5B28资讯网——每日最新资讯28at.com

4. 其他重要方法

a. allOf(CompletableFuture<?>... cfs)

创建一个新的 CompletableFuture,当所有给定的 CompletableFuture 都完成(不论成功与否)时,新 CompletableFuture 完成。e5B28资讯网——每日最新资讯28at.com

b. anyOf(CompletableFuture<?>... cfs)

创建一个新的 CompletableFuture,当任意一个给定的 CompletableFuture 完成时,新 CompletableFuture 完成。e5B28资讯网——每日最新资讯28at.com

实战应用

CompletableFuture 的使用场景很广泛,例如e5B28资讯网——每日最新资讯28at.com

  1. 异步数据库查询与结果合并
  2. 微服务间异步通信
  3. 并行任务执行与结果汇总
  4. 异步事件处理与通知

这里以第一个场景举例:场景:在一个订单处理系统中,需要查询订单的详细信息、关联的商品信息以及用户的个人信息。为减少查询延迟,可以使用 CompletableFuture 对每个查询进行异步执行,并在所有查询完成后合并结果。示例:e5B28资讯网——每日最新资讯28at.com

如果我们不使用Java8提供的这个CompletableFuture 来实现e5B28资讯网——每日最新资讯28at.com

@Service@RequiredArgsConstructorpublic class OrderProcessingServiceLegacy {    private final OrderRepository orderRepo;    private final ProductRepository productRepo;    private final UserRepository userRepo;    public OrderDetails fetchOrderDetails(int orderId) throws InterruptedException {        ExecutorService executor = Executors.newFixedThreadPool(3);        CountDownLatch orderLatch = new CountDownLatch(1);        CountDownLatch productsLatch = new CountDownLatch(1);        CountDownLatch userLatch = new CountDownLatch(1);        Order order = null;        List<Product> products = null;        User user = null;        // 异步查询订单        executor.execute(() -> {            try {                order = orderRepo.findOrderById(orderId);                orderLatch.countDown();            } finally {                productsLatch.countDown();            }        });        // 异步查询商品        executor.execute(() -> {            try {                products = productRepo.findProductsByOrderId(orderId);            } finally {                productsLatch.countDown();            }        });        // 异步查询用户(等待订单查询完成后再执行)        executor.execute(() -> {            try {                orderLatch.await(); // 确保订单查询已完成                user = userRepo.findUserById(order.getCustomerId());            } finally {                userLatch.countDown();            }        });        // 等待所有查询完成        userLatch.await();        return new OrderDetails(order, products, user);    }    // ... 其他方法 ... @Data @AllArgsConstructor     public static class OrderDetails {        private final Order order;        private final List<Product> products;        private final User user;    }}

使用CompletableFuture实现e5B28资讯网——每日最新资讯28at.com

@Service@RequiredArgsConstructorpublic class OrderProcessingService {    private final OrderRepository orderRepo;    private final ProductRepository productRepo;    private final UserRepository userRepo; private final ThreadPoolExecutor executor;    public CompletableFuture<OrderDetails> fetchOrderDetails(int orderId) {        CompletableFuture<Order> orderFuture = CompletableFuture.supplyAsync(() -> orderRepo.findOrderById(orderId), executor);        CompletableFuture<List<Product>> productsFuture = CompletableFuture.supplyAsync(() -> productRepo.findProductsByOrderId(orderId), executor);        CompletableFuture<User> userFuture = CompletableFuture.supplyAsync(() -> userRepo.findUserById(order.getCustomerId()), executor);        return CompletableFuture.allOf(orderFuture, productsFuture, userFuture)                .thenApplyAsync(unused -> {                    Order order = orderFuture.join();                    List<Product> products = productsFuture.join();                    User user = userFuture.join();                    return new OrderDetails(order, products, user);                }, executor);    }    // ... 其他方法 ... @Data    public static class OrderDetails {        private final Order order;        private final List<Product> products;        private final User user;    }}

在这个示例中:e5B28资讯网——每日最新资讯28at.com

  • 使用了CompletableFuture之后,代码量减少了,整洁度和可读性也得到提高。
  • fetchOrderDetails 方法接受一个订单 ID,使用 CompletableFuture.supplyAsync() 异步查询订单、商品和用户信息。
  • 使用 CompletableFuture.allOf() 监控所有查询的完成状态。
  • 当所有查询完成时,使用 thenApplyAsync() 合并结果,创建一个包含完整订单详情的 OrderDetails 对象。

小结

CompletableFuture 作为 Java 8 引入的重要异步编程工具,极大地提升了 Java 平台在应对高并发、高性能场景的能力。结合 Java 8 的并行流(Stream.parallel())与 CompletableFuture,可以轻松实现数据集的并行处理和结果聚合。下次给大家聊聊Stream.parallel()。e5B28资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-84006-0.htmlCompletableFuture:Java 8 中的异步编程利器

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: 详解Spring Boot中Payload(负载)的概念与实践

下一篇: 电商真实对账系统是如何设计并优化的

标签:
  • 热门焦点
  • 6月安卓手机性价比榜:Note 12 Turbo断层式碾压

    6月份有一个618,虽然这是京东周年庆的日子,但别的电商也都不约而同的跟进了,反正促销没坏处,厂商和用户都能满意。618期间一些产品也出现了历史低价,那么各个价位段的产品性价比
  • 一年经验在二线城市面试后端的经验分享

    忠告这篇文章只适合2年内工作经验、甚至没有工作经验的朋友阅读。如果你是2年以上工作经验,请果断划走,对你没啥帮助~主人公这篇文章内容来自 「升职加薪」星球星友 的投稿,坐
  • 如何使用JavaScript创建一只图像放大镜?

    译者 | 布加迪审校 | 重楼如果您曾经浏览过购物网站,可能遇到过图像放大功能。它可以让您放大图像的特定区域,以便浏览。结合这个小小的重要功能可以大大改善您网站的用户体验
  • 微信语音大揭秘:为什么禁止转发?

    大家好,我是你们的小米。今天,我要和大家聊一个有趣的话题:为什么微信语音不可以转发?这是一个我们经常在日常使用中遇到的问题,也是一个让很多人好奇的问题。让我们一起来揭开这
  • 虚拟键盘 API 的妙用

    你是否在遇到过这样的问题:移动设备上有一个固定元素,当激活虚拟键盘时,该元素被隐藏在了键盘下方?多年来,这一直是 Web 上的默认行为,在本文中,我们将探讨这个问题、为什么会发生
  • 华为和江淮汽车合作开发百万元问界MPV?双方回应来了

    8月1日消息,郭明錤今天在社交平台发文称,华为正在和江淮汽车合作,开发售价在100万元的问界MPV,预计在2024年第2季度量产,销量目标为上市首年交付5万辆。
  • 华为Mate60标准版细节曝光:经典星环相机模组回归

    这段时间以来,关于华为新旗舰的爆料日渐密集。据此前多方爆料,今年华为将开始恢复一年双旗舰战略,除上半年推出的P60系列外,往年下半年的Mate系列也将
  • OPPO K11搭载长寿版100W超级闪充:26分钟充满100%

    据此前官方宣布,OPPO将于7月25日也就是今天下午14:30举办新品发布会,届时全新的OPPO K11将正式与大家见面,将主打旗舰影像,和同档位竞品相比,其最大的卖
  • OPPO K11采用全方位护眼屏:三大护眼能力减轻视觉疲劳

    日前OPPO官方宣布,全新的OPPO K11将于7月25日正式发布,将主打旗舰影像,和同档位竞品相比,其最大的卖点就是将配备索尼IMX890主摄,堪称是2000档位影像表
Top