GUAVA-ListenableFuture实现回调
随着软件开发的不断进步,在实际的开发应用中,可能一次请求需要查询若干次数据库或者调用若干次第三方,按照传统的串行执行的话,会大大增加响应时间,无法满足业务需求,更无法满足用户迫切需要响应迅速的愿望。对此,我们需要针对网络请求或内部调用中包含的“多任务”进行异步处理,并行去执行这些“任务”,这样就就会大大减小响应时间。本文是基于guava中的ListenableFuture来实现的。
测试代码:
package com.study1; import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.LockSupport; import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;
/**
* GUAVA ListenableFuture
* @author gaojy
*
*/
public class TestListenableFuture {
//定义一个线程池,用于处理所有任务
final static ListeningExecutorService service
= MoreExecutors.listeningDecorator(Executors.newCachedThreadPool()); public static void main(String[] args){
Long t1 = System.currentTimeMillis();
// 任务1
ListenableFuture<Boolean> booleanTask = service.submit(new Callable<Boolean>() {
@Override
public Boolean call() throws Exception {
Thread.sleep(10000);
return true;
}
}); /**
*
*/
Futures.addCallback(booleanTask, new FutureCallback<Boolean>() {
@Override
public void onSuccess(Boolean result) {
System.err.println("BooleanTask: " + result);
} @Override
public void onFailure(Throwable t) {
}
}); // 任务2
ListenableFuture<String> stringTask = service.submit(new Callable<String>() {
@Override
public String call() throws Exception {
Thread.sleep(10000);
return "Hello World";
}
}); Futures.addCallback(stringTask, new FutureCallback<String>() {
@Override
public void onSuccess(String result) {
System.err.println("StringTask: " + result);
} @Override
public void onFailure(Throwable t) {
}
}); // 任务3
ListenableFuture<Integer> integerTask = service.submit(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
Thread.sleep(10000);
return new Random().nextInt(100);
}
}); Futures.addCallback(integerTask, new FutureCallback<Integer>() {
@Override
public void onSuccess(Integer result) {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.err.println("IntegerTask: " + result);
} @Override
public void onFailure(Throwable t) {
}
}); // 执行时间
System.err.println("time: " + (System.currentTimeMillis() - t1)); }
}
测试结果:

源码分析:
在26行中ListeningExecutorService的submit()方法:
public ListenableFuture submit(Runnable task, Object result)
{
// 初始化了ListenableFutureTask对象
ListenableFutureTask ftask = ListenableFutureTask.create(task, result);
//执行task,实际上调用了Callable对象的call()方法
execute(ftask);
return ftask;
}
再来查看一下Futures.addCallback的方法:
public static void addCallback(ListenableFuture future, FutureCallback callback, Executor executor)
{
//对回调task进行检查
Preconditions.checkNotNull(callback);
//创建一个新的Runnable对象,并放到一个指定的线程中,执行。
//这个Runnable对象主要任务就是获得future的结果,并根据结果调用回调函数的相应方法
Runnable callbackListener = new Runnable(future, callback) { public void run()
{
Object value;
try
{
//获取future执行结果,内部调用future.get(),产生堵塞,而不影响main主线程的执行,当获取到value时,就调用callback的onSuccess()方法
value = Uninterruptibles.getUninterruptibly(future);
}
catch(ExecutionException e)
{
callback.onFailure(e.getCause());
return;
}
catch(RuntimeException e)
{
callback.onFailure(e);
return;
}
catch(Error e)
{
callback.onFailure(e);
return;
}
callback.onSuccess(value);
} final ListenableFuture val$future;
final FutureCallback val$callback; {
future = listenablefuture;
callback = futurecallback;
super();
}
}
;
future.addListener(callbackListener, executor);
}
GUAVA-ListenableFuture实现回调的更多相关文章
- 从Java future 到 Guava ListenableFuture实现异步调用
从Java future 到 Guava ListenableFuture实现异步调用 置顶 2016年04月24日 09:11:14 皮斯特劳沃 阅读数:17570 标签: java异步调用线程非阻 ...
- 从Java Future到Guava ListenableFuture实现异步调用
原文地址: http://blog.csdn.net/pistolove/article/details/51232004 Java Future 通过Executors可以创建不同类似的线程 ...
- google Guava包的ListenableFuture解析
一. ListenableFuture是用来增强Future的功能的. 我们知道Future表示一个异步计算任务,当任务完成时可以得到计算结果.如果我们希望一旦计算完成就拿到结果展示给用户或者做另外 ...
- Future 异步回调 大起底之 Java Future 与 Guava Future
目录 写在前面 1. Future模式异步回调大起底 1.1. 从泡茶的案例说起 1.2. 何为异步回调 1.2.1. 同步.异步.阻塞.非阻塞 1.2.2. 阻塞模式的泡茶案例图解 1.2.3. 回 ...
- Guava - 并行编程Futures
Guava为Java并行编程Future提供了很多有用扩展,其主要接口为ListenableFuture,并借助于Futures静态扩展. 继承至Future的ListenableFuture,允许我 ...
- 初探Google Guava
Guava地址:https://github.com/google/guava 第一次接触我是在16年春github上,当时在找单机查缓存方法,google guava当初取名是因为JAVA的类库不好 ...
- Guava future
减少主函数的等待时间,使得多任务能够异步非阻塞执行 ListenableFuture是可以监听的Future,它是对java原生Future的扩展增强.Future表示一个异步计算任务,当任务完成时可 ...
- 多线程学习-ListenableFuture使用介绍以及示例
Guava为Java并行编程Future提供了很多有用扩展,其主要接口为ListenableFuture,并借助于Futures静态扩展.ListenableFuture顾名思义就是可以监听的Futu ...
- Java设计模式补充:回调模式、事件监听器模式、观察者模式(转)
一.回调函数 为什么首先会讲回调函数呢?因为这个是理解监听器.观察者模式的关键. 什么是回调函数 所谓的回调,用于回调的函数. 回调函数只是一个功能片段,由用户按照回调函数调用约定来实现的一个函数. ...
- Guava cacha 机制及源码分析
1.ehcahce 什么时候用比较好:2.问题:当有个消息的key不在guava里面的话,如果大量的消息过来,会同时请求数据库吗?还是只有一个请求数据库,其他的等待第一个把数据从DB加载到Guava中 ...
随机推荐
- 使用queue 做一个分布式爬虫(一)
这个作为调配的 taskMaster.py #!/usr/bin/env python # -*- coding: utf-8 -*- # @Time : 2018/12/23 15:21 # @au ...
- SSM框架整合的最新打开方式(打造最详细的SSM整合教程)
SSM整合 文章已托管到GitHub,大家可以去GitHub查看阅读,欢迎老板们前来Star!搜索关注微信公众号 [码出Offer] 领取各种学习资料! SSM 一.创建一个Maven项目 File ...
- 2.pandas的数据结构
对于文件来说,读取只是最初级的要求,那我们要对文件进行数据分析,首先就应该要知道,pandas会将我们熟悉的文件转换成了什么形式的数据结构,以便于后续的操作 数据结构 pandas对文件一共有两种数据 ...
- php imap 那些坑
今天调试php 接收邮件,遇见的几大坑! 第一,返回错误 关键字imap_open返回flase 原来{{$mailServer}:143}INBOX 的端口,不是根据outlook给的,,,,,是 ...
- Kaggle 入门题-泰坦尼克号灾难存活预测
这个题目的背景概况来讲就是基于泰坦尼克号这个事件,然后大量的人员不幸淹没在这个海难中,也有少部分人员在这次事件之中存活,然后这个问题提供了一些人员的信息如姓名.年龄.性别.票价,所在客舱等等一些信息, ...
- 交通网最短路径长 dp c++
// // Created by Arc on 2020/4/26. // /* * 城市交通线路,单向通行,道路之间可能有不通,每条连同的路之间都有相应的费用 * 求从起点到终点的最小费用 * * ...
- setTimeout、clearTimeout、setInterval
setTimeout(cb, ms) setTimeout(cb, ms) 全局函数在指定的毫秒(ms)数后执行指定函数(cb).:setTimeout() 只执行一次指定函数. 返回一个代表定时器的 ...
- PHP 数据库 ODBC创建 ODBC 连接
PHP 数据库 ODBC ODBC 是一种应用程序编程接口(Application Programming Interface,API),使我们有能力连接到某个数据源(比如一个 MS Access 数 ...
- PHP fileperms() 函数
定义和用法 fileperms() 函数返回文件或目录的权限. 如果成功,该函数以数字形式返回权限.如果失败,则返回 FALSE. 语法 fileperms(filename) 参数 描述 filen ...
- Fragment为什么须要无参构造方法
日前在项目代码里遇到偷懒使用重写Fragment带参构造方法来传参的做法,顿生好奇,继承android.support.v4.app.Fragment而又不写无参构造方法不是会出现lint错误编译不通 ...