Guava库学习:学习Concurrency(四)FutureCallback
链接地址:http://www.xx566.com/detail/159.html
上一篇,Guava库学习:学习Concurrency(三)ListenableFuture中, 我们最后说到,ListenableFuture.addListener方法并没有返回值,我们不能区别的处理任务成功后失败的情况,Guava提供了 FutureCallback接口,FutureCallback接口提供了onSuccess 和onFailure 方法,onSuccess 方法以Future任务的执行结果作为参数,因此我们就可以在成功时候获取任务执行的结果,做进一步的处理了,本篇,我们就来进行 Concurrency(四)FutureCallback接口的学习。
使用FutureCallback
使用 FutureCallback非常简单,我们以类似的方式向ListenableFuture注册一个回调接口,我们不需要直接向 ListenableFuture添加FutureCallback回调函数,而是直接使用Futures.addCallback方法。Futures 类提供了一些有用的、用于处理Future实例的静态方法集合,接下来我们来看一个例子,首先来看一个简单的FutureCallback接口的实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | class FutureCallbackImpl implements FutureCallback<String> { private StringBuilder builder = new StringBuilder(); @Override public void onSuccess(String result) { builder.append(result).append( " successfully" ); } @Override public void onFailure(Throwable t) { builder.append(t.toString()); } public String getCallbackResult() { return builder.toString(); } } |
在上面的例子中,我们在onSuccess方法中捕获到了任务执行的结果,并将结果追加字符" successfully",在异常的情况下,我们通过Throwable对象获取到了异常信息,来看下面的一个完整的应用例子,如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | @Test public void testFutureCallback() { // 创建一个线程缓冲池Service ExecutorService executor = Executors.newCachedThreadPool(); //创建一个ListeningExecutorService实例 ListeningExecutorService executorService = MoreExecutors.listeningDecorator(executor); //提交一个可监听的线程 ListenableFuture<String> futureTask = executorService.submit ( new Callable<String>() { @Override public String call() throws Exception { return "Task completed" ; } }); FutureCallbackImpl callback = new FutureCallbackImpl(); //线程结果处理回调函数 Futures.addCallback(futureTask, callback); //如果callback中执行的是比较费时的操作,Guava建议使用以下方法。 // Futures.addCallback(futureTask,callback,executorService); //处理后的线程执行结果:"Task completed successfully" assertThat(callback.getCallbackResult(), is( "Task completed successfully" )); } |
在上面的例子中,我们创建了一个ListenableFuture接口和一个FutureCallback接口的实现,并且注册,在 ListenableFuture实例完成后会立即执行回调函数,并且能够准确的捕获到执行结果进行处理。通常情况下,我们不想从 FutureCallback实例访问结果,而是让FutureCallback异步处理结果。如果提供的FutureCallback实例 执行的是比较费时的操作,使用如下的Futures.addCallback方法可能比较好:
1 | Futures.addCallback(futureTask,callback,executorService); |
注:关于Futures,请参阅:Guava库学习:学习Concurrency(八)Futures
通过这个方法,FutureCallback操作将会执行在单独的线程,这个线程由传入的ExecutorService参数提供。否则的话,初始 ListenableFuture实例执行的线程将会执行FutureCallback操作,就像ThreadPoolExecutor、 CallerRunsPolicy执行者服务,即任务将在调用者的线程上运行。
总结:FutureCallback接口用于处理任务完成或失败后的结果,适用于在多线程并发编程中对Future结果的获取和处理,是对ListenableFuture接口很好的补充,弥补了ListenableFuture接口无法处理任务返回值的缺陷。
源码地址:http://git.oschina.net/realfighter/xx566-diary/blob/master/src/guava/FutureCallbackTest.java
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
2016-11-02 【转】Appium移动自动化测试(三)--安装Android模拟器
2016-11-02 appium环境搭建参考
2015-11-02 jmeter线程组之间传递参数