Google Guava –期货
这篇文章是我在Google Guava上的系列文章的延续,这次涵盖了Future。 Futures类是用于使用Future / ListenableFuture接口的静态实用程序方法的集合。 Future是提交给ExecutorService的异步任务(可运行或可调用)的句柄。 Future界面提供以下方法:获取任务的结果,检查任务是否完成或取消任务。 ListenableFuture接口扩展了Future接口,并添加了将完成侦听器设置为在任务完成后运行的功能。 要创建ListenableFuture,您首先需要装饰一个ExecutorService实例,如下所示:
ExecutorService executorService = MoreExecutors.listeningDecorator(Executors.newCachedThreadPool());
现在所有提交的Callables / Runnables将返回一个ListenableFuture。 MoreExecutors可以在com.google.common.util.concurrent包中找到。 ListenableFutures在覆盖以前的帖子 。 期货中有太多方法无法有效地涵盖在一篇文章中,所以我只涉及:链,转换,allAsList和successAsList。 在这篇文章中,我将交替使用Futures和ListenableFutures。
链
链方法返回一个ListenableFuture,其值是通过从输入Future中获取结果并将其作为参数应用到Function对象来计算的, Function对象又返回另一个ListenableFuture。 让我们看一个代码示例并逐步执行:
ListenableFuture<List<String>> indexSearch = luceneSearcher.searchAsync('firstName:martin');Function<List<String>, ListenableFuture<List<Person>>> queryFunction = new Function<List<String>, ListenableFuture<List<Person>>>() {@Overridepublic ListenableFuture<List<Person>> apply(final List<String> ids) {return dataService.getPersonsByIdAsync(ids);}};ListenableFuture<List<Person>> results = Futures.chain(indexSearch, queryFunction,executorService);
- 第1行正在使用Lucene执行异步搜索,并将返回一个ID列表,这些ID代表存储在数据库中的人员记录的主键。 (我创建了一个小索引,其中存储在Lucene中的唯一数据是id的数据,其余数据仅被索引了)。
- 第4 – 11行正在构建功能对象,其中apply方法将使用搜索未来的结果作为输入。 apply返回的将来是对dataService对象的调用的结果。
- 第12行是从链调用返回的未来。 一旦输入将来完成,将使用executorService运行该功能。
为了更加清楚,这是searchAsync和getPersonsByIdAsync方法的作用。 在前面的代码示例中,这些方法调用分别来自第2行和第8行:
public ListenableFuture<List<String>> searchAsync(final String query) {return executorService.submit(new Callable<List<String>>() {@Overridepublic List<String> call() throws Exception {return search(query);}});}public ListenableFuture<List<Person>> getPersonsByIdAsync(final List<String> ids) {return executorService.submit(new Callable<List<Person>>() {@Overridepublic List<Person> call() throws Exception {return getPersonsById(ids);}});}
chain方法具有两个签名:
- 链(ListentableFuture,函数)
- 链(ListenableFuture,函数,ExecutorService)
在确定使用哪种方法时,有几点要考虑。
如果通过调用时间链完成了输入将来,则所提供的函数将在调用线程中立即执行。 此外,如果未提供执行程序,则使用MoreExecutors.sameThreadExecutor。 MoreExecutors.sameThreadExecutor(顾名思义)位于ThreadPoolExecutor.CallerRunsPolicy之后,这意味着提交的任务在与执行/提交相同的线程中运行。
转变
转换方法类似于链式方法,因为它以Future和Function对象作为参数。 不同之处在于,不返回ListenableFuture,仅返回将给定功能应用于输入future的结果。 考虑以下:
List<String> ids = ....
ListenableFuture<List<Map<String, String>>> dbRecords = dataService.getPersonDataByIdAsync(ids);Function<List<Map<String, String>>,List<Person>> transformDbResults = new Function<List<String>, List<Person>>() {@Overridepublic List<Person> apply(List<Map<String, String>> personMapList) {List<Person> personObjList = new ArrayList<Person>();for(Map<String,String> personDataMap : personMapList){personObjList.add(new Person(personDataMap);} return personObjList;}};ListenableFuture<List<Person>> transformedResults = Futures.transform(dbRecords, transformDbResults, executorService);
- 在第2行上,执行异步数据库查找
- 在第4行上,正在创建一个函数对象,但是在第8行上,请注意返回类型为List <Person>
transform方法具有与chain相同的重载方法调用,但有相同的警告。
AllAsList
allAsList方法将采用任意数量的ListenableFutures作为变量或以Iterator <ListenableFuture>的形式。 返回一个ListenableFuture,其值是所有输入结果的列表。 列表中返回的值与原始列表的顺序相同。 如果任何输入值被取消或失败,则返回的ListenableFuture也将被取消或失败。 从allAsList调用取消返回的future不会传播到列表中提交的任何原始任务。
ListenableFuture<List<Person>> lf1 = getPersonsByFirstNameFuture('martin');
ListenableFuture<List<Person>> lf2 = getPersonsByFirstNameFuture('bob');
ListenableFuture<List<List<Person>>> lfResults = Futures.allAsList(lf1, lf2);
//assume lf1 failed
List<List<Person>> personLists = lfResults.get() //call results in exception
成功名单
successAsList方法与allAsList非常相似,但是更加宽容。 就像allAsList一样,successAsList返回结果列表的顺序与输入列表的顺序相同,但是如果任何输入失败或被取消,则列表中的相应值将为null。 取消返回的将来也不会取消任何原始输入。
ListenableFuture<List<Person>> lf1 = getPersonsByFirstNameFuture('martin');
ListenableFuture<List<Person>> lf2 = getPersonsByFirstNameFuture('bob');
ListenableFuture<List<List<Person>>> lfResults = Futures.successfulAsList(lf1, lf2);
//assume lf1 failed
List<List<Person>> personLists = lfResults.get();
List<Person> listOne = personLists.get(0) //listOne is null
List<Person> listTwo = personLists.get(1) //listTwo, not null
结论
希望这有助于发现Google Guava的Futures类中包含的有用性。 我创建了一个单元测试,以显示本文中描述的方法的示例用法。 由于有大量支持代码,因此我在gihub上创建了一个项目guava-blog 。 该项目还将包含我以前在Guava上发表的文章( Monitor , ListenableFuture )的源代码。 一如既往地欢迎提出意见和建议。
资源资源
- 番石榴项目首页
- 期货API
- 博客系列的源代码
参考资料: Google Guava – JCG合作伙伴 Bill Bejeck的期货,来自Random Thoughts On Coding博客。
翻译自: https://www.javacodegeeks.com/2012/11/google-guava-futures.html
Google Guava –期货相关推荐
- 谷歌guava_Google Guava –期货
谷歌guava 这篇文章是我在Google Guava上的系列文章的延续,这次涵盖了Future. Futures类是用于使用Future / ListenableFuture接口的静态实用程序方法的 ...
- Error:Could not download guava.jar (com.google.guava:guava:19.0): No cached version available for of
今天从git导入demo 报错 Error:Could not download guava.jar (com.google.guava:guava:19.0): No cached version ...
- 为什么我不建议你用阿里巴巴Java规范,而使用 Google Guava 编程?
点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! 来自 | 张丰哲 链接 | www.jianshu.com ...
- 为什么推荐 Java 程序员使用 Google Guava 编程
点击上方"方志朋",选择"设为星标" 做积极的人,而不是积极废人 来自 | 张丰哲 链接 | www.jianshu.com/p/97778b21bd00 前言 ...
- [Google Guava] 1.3-常见Object方法
原文链接 译者: 沈义扬 equals 当一个对象中的字段可以为null时,实现Object.equals方法会很痛苦,因为不得不分别对它们进行null检查.使用Objects.equal帮助你执行n ...
- Google Guava Collections 使用介绍
原帖http://www.open-open.com/lib/view/open1325143343733.html 简介: Google Guava Collections 是一个对 Java Co ...
- [Google Guava] 3-缓存
原文地址 译文地址 译者:许巧辉 校对:沈义扬 范例 01 LoadingCache<Key, Graph> graphs = CacheBuilder.newBuilder() ...
- [Google Guava] 11-事件总线
原文链接 译文连接 译者:沈义扬 传统上,Java的进程内事件分发都是通过发布者和订阅者之间的显式注册实现的.设计EventBus就是为了取代这种显示注册方式,使组件间有了更好的解耦.EventBus ...
- [Google Guava] 2.4-集合扩展工具类
原文链接 译文链接 译者:沈义扬,校对:丁一 简介 有时候你需要实现自己的集合扩展.也许你想要在元素被添加到列表时增加特定的行为,或者你想实现一个Iterable,其底层实际上是遍历数据库查询的结果集 ...
最新文章
- 利用追赶法来求解方程Ax=b的C++程序
- 江苏省计算机学会科学技术奖,孙国梓
- 详细讲解Python中的self;什么是self?self的传参问题?
- java语言精粹_java 成神之路 (一)
- 源码nginx+php
- 可视化排班管理_人事工资管理系统就选i人事,提升算薪效率聚焦战略决策
- 群晖3617可以有几个网卡_一步到位,购入群晖920+和它的小伙伴们
- delphi csdn论坛技巧收藏贴
- 深圳市计算机软件著作权资助,深圳市计算机软件著作权登记资助管理实施细则...
- 英国essay与澳洲essay写作区别以及注意事项
- 跟读 播放器 android,安卓手机英语学习利器 android 英语复读 跟读 练听力 练口语...
- android友盟微信授权登录清除,【转载】Android友盟SDK微信授权登录接入
- 和中国移动对接短信平台
- Python基础提高
- 因为一个小功能,我对微信手机号转账的好感度加了10分
- python自动识别简单图片中的文字
- IDEA 更新到 2021.2.3 咋样?【2021.3、2021.3.1看评论区】
- TCP握手机制、TCP长连接和短连接、TCP 保活机制 、心跳机制
- Ubuntu 16.04 英伟达驱动、常用软件以及虚拟环境的安装
- Idea 中解决git冲突
热门文章
- python开发stm32软件_ADB+Python+STM32 实现 微信跳一跳辅助
- date转timestamp格式_技术分享 | MySQL:timestamp 时区转换导致 CPU %sys 高的问题
- 转:并发与并行的区别
- intro to JNDI
- SpringBoot整合Redis要注意的那些
- java gradle构建_在Gradle中为JPMS构建Java 6-8库
- 困难是成功路上的垫脚石_Java是开发的垫脚石。 学习吧!
- system.gc 性能_使用这些先进的GC技术提高应用程序性能
- maven 生成本地库_在2017年从Maven工件生成P2存储库
- guice 实例_使用Google Guice消除实例之间的歧义