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
方法实现。其主要作用是:
- 如果
CompletableFuture
已完成,返回结果值或抛出异常 - 如果未完成,则返回给定的默认值
valueIfAbsent
详细解释:
-
方法签名:
public T getNow(T valueIfAbsent)
- 返回类型
T
: 泛型类型,表示结果的类型 - 参数
valueIfAbsent
: 当 Future 未完成时返回的默认值
- 返回类型
-
方法实现:
Object r; return ((r = result) == null) ? valueIfAbsent : reportJoin(r);
r
是一个临时变量,用于存储result
字段的值result
是CompletableFuture
的内部字段,存储计算结果- 使用三元运算符判断:
- 如果
result
为 null (未完成),返回valueIfAbsent
- 否则,调用
reportJoin(r)
处理并返回结果
- 如果
-
reportJoin(r)
方法:- 负责处理已完成的结果
- 可能会抛出
CancellationException
或CompletionException
总之,这个方法提供了一种非阻塞的方式来获取 CompletableFuture
的结果,同时允许指定一个默认值用于未完成的情况。
三、最佳实践 & 示例
CompletableFuture.getNow() 的最佳实践及示例如下:
- 用于非阻塞地获取结果
- 提供合理的默认值
- 处理可能的异常
- 避免在关键路径上频繁使用
示例代码:
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()
的几个关键用法:
- 立即获取结果,如果未完成则返回默认值
- 等待一段时间后再次获取结果
- 处理可能发生的异常
运行这段代码,你会看到类似以下输出:
立即获取的结果: 尚未完成
等待后获取的结果: 操作完成
捕获到异常: java.lang.RuntimeException: 操作失败
最佳实践提示:
- 提供有意义的默认值,确保程序在未获得实际结果时也能正常运行
- 考虑使用
orTimeout()
或completeOnTimeout()
方法来设置超时 - 在循环或高频调用中谨慎使用
getNow()
,因为它可能影响性能 - 对于关键操作,考虑使用
get()
或join()
方法等待结果完成 - 始终处理可能抛出的异常,特别是
CompletionException
原文地址:https://blog.csdn.net/wangnanwlw/article/details/145314866
免责声明:本站文章内容转载自网络资源,如侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!