1. 引子
ListenableFuture顾名思义就是能够监听的Future,它是对java原生Future的扩展加强。咱们知道Future表示一个异步计算任务,当任务完成时能够获得计算结果。若是咱们但愿一旦计算完成就拿到结果展现给用户或者作另外的计算,就必须使用另外一个线程不断的查询计算状态。这样作,代码复杂,并且效率低下。使用ListenableFuture Guava帮咱们检测Future是否完成了,若是完成就自动调用回调函数,这样能够减小并发程序的复杂度。java
ListenableFuture是一个接口,它从jdk的Future接口继承,添加了void addListener(Runnable listener, Executor executor)方法。并发
咱们看下如何使用ListenableFuture。首先须要定义ListenableFuture的实例。异步
ListeningExecutorService executorService = MoreExecutors.listeningDecorator(Executors.newCachedThreadPool()); final ListenableFuture<Integer> listenableFuture = executorService.submit(new Callable<Integer>() { @Override public Integer call() throws Exception { System.out.println("call execute.."); TimeUnit.SECONDS.sleep(1); return 7; } });
ListeningExecutorService executorService = MoreExecutors.listeningDecorator(Executors.newCachedThreadPool()); final ListenableFuture<Integer> listenableFuture = executorService.submit(new Callable<Integer>() { @Override public Integer call() throws Exception { System.out.println("call execute.."); TimeUnit.SECONDS.sleep(1); return 7; } });
首先经过MoreExecutors类的静态方法listeningDecorator方法初始化一个ListeningExecutorService的方法,而后使用此实例的submit方法便可初始化ListenableFuture对象。ide
咱们上文中定义的ListenableFuture要作的工做,在Callable接口的实现类中定义,这里只是休眠了1秒钟而后返回一个数字7.函数
有了ListenableFuture实例,有两种方法能够执行此Future并执行Future完成以后的回调函数。spa
方法一:经过ListenableFuture的addListener方法线程
listenableFuture.addListener(new Runnable() { @Override public void run() { try { System.out.println("get listenable future's result " + listenableFuture.get()); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } } }, executorService);
listenableFuture.addListener(new Runnable() { @Override public void run() { try { System.out.println("get listenable future's result " + listenableFuture.get()); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } } }, executorService);
方法二:经过Futures的静态方法addCallback给ListenableFuture添加回调函数code
Futures.addCallback(listenableFuture, new FutureCallback<Integer>() { @Override public void onSuccess(Integer result) { System.out.println("get listenable future's result with callback " + result); } @Override public void onFailure(Throwable t) { t.printStackTrace(); } });
Futures.addCallback(listenableFuture, new FutureCallback<Integer>() { @Override public void onSuccess(Integer result) { System.out.println("get listenable future's result with callback " + result); } @Override public void onFailure(Throwable t) { t.printStackTrace(); } });
推荐使用第二种方法,由于第二种方法能够直接获得Future的返回值,或者处理错误状况。本质上第二种方法是经过调动第一种方法实现的,作了进一步的封装。对象
另外ListenableFuture还有其余几种内置实现:继承
- SettableFuture:不须要实现一个方法来计算返回值,而只须要返回一个固定值来作为返回值,能够经过程序设置此Future的返回值或者异常信息
- CheckedFuture: 这是一个继承自ListenableFuture接口,他提供了checkedGet()方法,此方法在Future执行发生异常时,能够抛出指定类型的异常。
参考:
http://outofmemory.cn/java/guava/concurrent/ListenableFuture