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接口的实现:

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对象获取到了异常信息,来看下面的一个完整的应用例子,如下:

    @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方法可能比较好:

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

posted @ 2020-11-02 20:21  飘飘雪  阅读(1390)  评论(1编辑  收藏  举报