当前位置:网站首页>Gauva的ListenableFuture
Gauva的ListenableFuture
2022-08-03 08:08:00 【鲲鹏飞九万里】
Guava的ListenableFuture
一、ListenableFuture 介绍
并发是一个困难问题,但是通过强大和强大的抽象能够显著的简化工作。为了简化问题,Gauva使用ListenableFuture扩展了JDK的Future接口,
**我们强烈建议你在你所有的代码中使用ListenableFuture代替Future,**因为:
- 大多数的
Future方法需要它; - 这比以后更改为
ListenableFuture更容易; - 实用方法的提供者不需要提供
Future和ListenableFuture方法的变体;
二、接口
传统的Future代表着异步计算的结果:一个计算可能也可能没有完成生成结果。Future可以是一个程序计算的句柄,一个来自服务的承诺提供给我们一个结果。
ListenableFuture允许你注册一个回调函数,一旦计算是完成或者计算是已经完成,回调函数会立马执行。这个简单的添加能有效的支持多种Future接口不支持的操作。
基础的操作被ListenableFuture添加是通过addListener(Runnable, Executor),它指定了当Future的计算完成之后,指定的Runnable将会在Executor中执行。
三、添加回调函数
大多数用户更喜欢使用Futures.addCallback(ListenableFuture, FutureCallback, Executor),一个FutueCallback有两个方法:
onSuccess(V)如果future执行成功,基于结果进行执行。onFailure(Throwable)如果future执行失败,基于失败进行执行。
四、创建
相对于JDKExecutorService.submit(Callable) 方法初始化一个异步的计算。Guava提供了一个ListeningExecutorService 接口,它能在任何ExecutorService返回一个正常Future的地方,返回一个ListenableFuture。为了将ExecutorService转换成ListeningExecutorService ,仅需要使用MoreExecutors.listeningDecorator(executorService):
ListeningExecutorService service =
MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(
Runtime.getRuntime().availableProcessors()));
ListenableFuture<String> listenableFuture = service.submit(() -> callDemo());
Futures.addCallback(listenableFuture, new FutureCallback<String>() {
@Override
public void onSuccess(String result) {
System.out.println("Run Ok : " + result);
// service.shutdown();
}
@Override
public void onFailure(Throwable t) {
System.out.println("Run Fail: " + t);
}
}, service);
或者,如果你从一个基于FutureTask的API进行转换,Guava提供了ListenableFutureTask.create(Callable) 和ListenableFutureTask.create(Runnable, V) 。并不像JDK,ListenableFutureTask并不意味着直接扩展。
如果您更喜欢设置未来值的抽象而不是实现计算值的方法,请考虑扩展 AbstractFuture<V> 或直接使用 SettableFuture。
如果你必须将另一个API提供的Future转换成ListenableFuture,你没有选择除了使用重量级的JdkFutureAdapters.listenInPoolThread(Future) ,将Future转化成ListenableFuture。无论什么时候,只要有可能,都应该修改源代码去返回一个ListenableFuture。
五、应用
使用ListenableFuture的重要原因是,它让异步的链操作成为可能。
很多有效的其它操作使用ListenableFuture是支持的,而单独使用Future是不支持的。不同的操作能够被不同的Executor执行,并且单个 ListenableFuture 可以有多个等待它的操作。
当多个操作应该在另一个操作开始时立即开始时——“扇出”——ListenableFuture 才起作用:它触发所有请求的回调。通过稍微多一点的工作,我们能“扇入”,或触发ListenableFuture进行计算只要若干个其它的Future执行完(看:Futures.allAsList)。
| 方法 | 描述 | 延伸 |
|---|---|---|
Futures.transformAsync(ListenableFuture, AsyncFunction, Executor) | 返回一个新的ListenableFuture,它的结果是应用AsyncFunction。AsyncFunction是对ListenableFuture结果的加工 | |
Futures.transform(ListenableFuture, Function, Executor) | 返回一个新的ListenableFuture,它的结果是应用Function。Function是对ListenableFuture结果的加工 | |
Futures.allAsList(Iterable<ListenableFuture<V>>) | 返回一个ListenableFuture,它的值是一个list包含了每一个输入输入future的值。如果任何的future失败或取消,这个future也失败或取消。 | |
Futures.successfulAsList(Iterable<ListenableFuture>) | 返回一个ListenableFuture,它的值是一个list包含了每一个输入输入future的值。如果相对应的future失败或取消,将用null代替。 |
一个AsyncFunction 提供了一个方法ListenableFuture<B> apply(A a)。它用于异步传输一个值。
六、避免内嵌的Future
ListenableFuture<ListenableFuture<String>> nestedFuture =
executorService.submit(() -> otherExecutorService.submit(() -> callDemo()));
上面的代码是不正确的, 因为如果外部Future的取消与外部Future的完成竞争,则该取消不会传播到内部Future。 使用 get() 或侦听器检查其他Future的失败也是一个常见错误,但除非特别注意,否则从 otherCallable 抛出的异常将被抑制。
为了避免这种情况,Guava 的所有Future处理方法(以及一些来自 JDK)都有 *Async 版本,可以安全地解开这个嵌套:
Futures.transformAsync(ListenableFuture, AsyncFunction, Executor)ExecutorService.submit(Callable)Futures.submitAsync(AsyncCallable, Executor)
边栏推荐
- Postman will return to results generated CSV file to the local interface
- 面渣逆袭:MySQL六十六问,两万字+五十图详解
- MySQL数据库————数据库与vs的连接
- 解决GANs训练中模式崩塌/训练崩溃的十五个方法
- mysqlbinlog: unknown variable 'default-character-set=utf8'
- C# 一周入门高级编程之《C#-继承》Day One
- 如何在安装GBase 8c数据库的时候,报错显示“Host ips belong to different cluster?
- 审批流设计
- tolower函数
- HCIP实验(06)
猜你喜欢

HCIP实验(06)

requests库

Roson的Qt之旅#104 QML Image控件

Evaluate:huggingface评价指标模块入门详细介绍

Eject stubborn hard drives with diskpart's offline command

FusionAccess软件架构、FusionAccess必须配置的四个组件、桌面发放流程、虚拟机组类型、桌面组类型

MySQL数据库————数据库与vs的连接

Dapr 与 NestJs ,实战编写一个 Pub & Sub 装饰器

AI mid-stage sequence labeling task: three data set construction process records

热部署系统实现
随机推荐
The Transformer, BERT, GPT paper intensive reading notes
Nacos使用实践
“==”和equals的区别
使用pipreqs导出项目所需的requirements.txt(而非整个环境)
Evaluate:huggingface评价指标模块入门详细介绍
“唯一索引允许为空“ 的说法是不严谨的
[Kaggle combat] Prediction of the number of survivors of the Titanic (from zero to submission to Kaggle to model saving and restoration)
@Async注解的坑,小心
国内IT市场还有发展吗?有哪些创新好用的IT运维工具可以推荐?
tolower函数
牛客 - 最佳直播时间 (差分)
netstat 及 ifconfig 是如何工作的。
C# 一周入门高级编程之《C#-继承》Day One
五、《图解HTTP》报文首部和HTTP缓存
PowerShell:执行 Install-Module 时,不能从 URI 下载
并发之ReentrantLock
mysql5.7服务器The innodb_system data file 'ibdata1' must be writable导致无法启动服务器
Redis的基础与django使用redis
训练正常&异常的GAN损失函数loss变化应该是怎么样的
BOM系列之localStorage