自学内容网 自学内容网

CompletableFuture#getNow 源码解析&最佳实践

一、源码


    /**
     * Returns the result value (or throws any encountered exception)
     * if completed, else returns the given valueIfAbsent.
     *
     * @param valueIfAbsent the value to return if not completed
     * @return the result value, if completed, else the given valueIfAbsent
     * @throws CancellationException if the computation was cancelled
     * @throws CompletionException if this future completed
     * exceptionally or a completion computation threw an exception
     */
    public T getNow(T valueIfAbsent) {
        Object r;
        return ((r = result) == null) ? valueIfAbsent : reportJoin(r);
    }

二、源码解析

这段代码是 CompletableFuture 类中的 getNow 方法实现。其主要作用是:

  1. 如果 CompletableFuture 已完成,返回结果值或抛出异常
  2. 如果未完成,则返回给定的默认值 valueIfAbsent

详细解释:

  1. 方法签名: public T getNow(T valueIfAbsent)

    • 返回类型 T: 泛型类型,表示结果的类型
    • 参数 valueIfAbsent: 当 Future 未完成时返回的默认值
  2. 方法实现:

    Object r;
    return ((r = result) == null) ? valueIfAbsent : reportJoin(r);
    
    • r 是一个临时变量,用于存储 result 字段的值
    • resultCompletableFuture 的内部字段,存储计算结果
    • 使用三元运算符判断:
      • 如果 result 为 null (未完成),返回 valueIfAbsent
      • 否则,调用 reportJoin(r) 处理并返回结果
  3. reportJoin(r) 方法:

    • 负责处理已完成的结果
    • 可能会抛出 CancellationExceptionCompletionException

总之,这个方法提供了一种非阻塞的方式来获取 CompletableFuture 的结果,同时允许指定一个默认值用于未完成的情况。

三、最佳实践 & 示例

CompletableFuture.getNow() 的最佳实践及示例如下:

  1. 用于非阻塞地获取结果
  2. 提供合理的默认值
  3. 处理可能的异常
  4. 避免在关键路径上频繁使用

示例代码:

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;

public class CompletableFutureNowExample {

    public static void main(String[] args) {
        // 创建一个CompletableFuture
        CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
            try {
                TimeUnit.SECONDS.sleep(2); // 模拟耗时操作
                return "操作完成";
            } catch (InterruptedException e) {
                return "操作被中断";
            }
        });

        // 使用getNow()立即获取结果
        String result = future.getNow("尚未完成");
        System.out.println("立即获取的结果: " + result);

        // 等待操作完成
        try {
            TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        // 再次使用getNow()获取结果
        result = future.getNow("尚未完成");
        System.out.println("等待后获取的结果: " + result);

        // 异常处理示例
        CompletableFuture<String> failedFuture = CompletableFuture.supplyAsync(() -> {
            throw new RuntimeException("操作失败");
        });

        try {
            String failedResult = failedFuture.getNow("发生错误");
            System.out.println("失败操作的结果: " + failedResult);
        } catch (Exception e) {
            System.out.println("捕获到异常: " + e.getMessage());
        }
    }
}

这个示例展示了 getNow() 的几个关键用法:

  1. 立即获取结果,如果未完成则返回默认值
  2. 等待一段时间后再次获取结果
  3. 处理可能发生的异常

运行这段代码,你会看到类似以下输出:

立即获取的结果: 尚未完成
等待后获取的结果: 操作完成
捕获到异常: java.lang.RuntimeException: 操作失败

最佳实践提示:

  1. 提供有意义的默认值,确保程序在未获得实际结果时也能正常运行
  2. 考虑使用 orTimeout()completeOnTimeout() 方法来设置超时
  3. 在循环或高频调用中谨慎使用 getNow(),因为它可能影响性能
  4. 对于关键操作,考虑使用 get()join() 方法等待结果完成
  5. 始终处理可能抛出的异常,特别是 CompletionException

原文地址:https://blog.csdn.net/wangnanwlw/article/details/145314866

免责声明:本站文章内容转载自网络资源,如侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!