FutureTask,基础异步回调框架
Runnable接口的run方法是无返回值的,为了获取线程运行的返回值,java引入了Callable接口,用来弥补这个缺憾。
代码实例:
FutureTask<Boolean> futureTask = new FutureTask(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
return 1;
}
});
Thread t = new Thread(futureTask);
t.start();
Integer b = f.get();
涉及的类图如下:
FutureTask的get方法类型与Thread的join方法类似,会阻塞主线程等待返回结果。换句话说这并不是异步回调。之所以介绍FutureTask,是因为它是异步回调的基础。
Guava:Google的扩展实现
为了实现异步回调,Google对Callable,Future 以及FutureTask 做个进一步的封装,增加对执行后结果的监听机制,以此实现异步回调效果(主线程可以不阻塞,执行其他操作,通过监听机制触发后续操作)。代码示例如下:
//初始化Callable
Callable<Integer> callable = new Callable<Integer>() {
@Override
public Integer call() throws Exception {
Thread.sleep(1000);
return 3;
}
};
//第一种实现方式,通过ListenableFuture和FutureCallback实现。
//初始化线程池
ExecutorService pool = Executors.newFixedThreadPool(10);
ListeningExecutorService lPool = MoreExecutors.listeningDecorator(pool);
//获取Future
ListenableFuture<Integer> l = lPool.submit(callable);
//为Future添加监听
Futures.addCallback(l, new FutureCallback<Integer>() {
@Override
public void onSuccess(@Nullable Integer integer) {
if(integer == 3){
System.out.println("haha");
}
}
@Override
public void onFailure(Throwable throwable) {
System.out.println("wanle");
}
});
//第二种方式,通过ListenableFutureTask实现
//获取可监听的FutureTask
ListenableFutureTask<Integer> futureTask = ListenableFutureTask.create(callable);
//添加监听
futureTask.addListener(new Runnable() {
@Override
public void run() {
System.out.println("laiyige");
}
},lPool);
//启动线程
new Thread(futureTask).start();
第一种方式引入了一个新的接口FutureCallback,根据业务代码的执行结果(成功,失败)执行对应的处理逻辑。第二种方式是对FutureTask的扩展,增加监听线程,在业务代码执行结束后启动监听的线程,执行后续处理逻辑。