Guava库学习:学习Concurrency(三)ListenableFuture

    链接地址:http://www.xx566.com/detail/158.html

    Java 5中引入了concurrent包,其中提供了许多重要的并发设计,其中一个便是Future对象,Future用于表示一个异步计算任务,我们通常需要 启动一个Executor实例,之后调用submit方法获取到Future对象,并通过future.get()方法获取线程执行完成后的结果,ListenableFuture接口继承了Future接口进行了扩展,允许我们注册一个Callback函数,并在任务完成后执行。

    

    下面是个简单的Future调用示例:

ExecutorService executor = Executors.newCachedThreadPool();
Future<Integer> future = executor.submit(new Callable<Integer>() {
    @Override
    public Integer call() throws Exception {
        //这里调用一些处理逻辑
        return 1 + 1;
    }
});

    更多Executor,请参阅:JavaSE_多线程 ,在上面的例子中,我们提交了一个Callable对象到ExecutorService实例,ExecutorService实例会立即返回Future对象,但是这并不意味着线程任务已经完成,要获取线程执行的结果,我们需要调用Future.get方法,但是如果任务并未完成的话会造成线程阻塞。

 

    ListenableFuture接口继承了Future接口进行了扩展,允许我们注册一个Callback函数,并在任务完成后执行。翻开ListenableFuture接口的源码,我们看到其中只定义了一个addListener方法,我们可以通过ListenableFuture.addListener,传入一个Runnable线程和ExecutorService对象,这个ExecutorService对象可以是提交原始任务的Executor实例,或者是完全的ExecutorService实例。

 

    获得ListenableFuture接口

    我 们知道,当一个Callable对象提交后,ExecutorService接口会返回一个Future对象,那么我们应该怎样获取到 ListenableFuture对象以便于我们设置Callback回调函数呢?Guava通过ListentingExecutorService接 口包装了ExecutorService对象,如下:

ListeningExecutorService executorService =
        MoreExecutors.listeningDecorator(executor);

    这里我们使用到了MoreExecutors类,其中包含了大量的静态方法用于处理Executor, ExecutorService和ThreadPool实例,翻开源码,整理其中的公共方法,如下:

 

getExitingExecutorService( ThreadPoolExecutor executor, long terminationTimeout, TimeUnit timeUnit):将给定的ThreadPoolExecutor转换成ExecutorService实例,在程序完成时退出, 它是通过使用守护线程和添加一个关闭钩子来等待他们完成。

getExitingScheduledExecutorService( ScheduledThreadPoolExecutor executor, long terminationTimeout, TimeUnit timeUnit):将给定的ScheduledThreadPoolExecutor转换成ScheduledExecutorService实例,在程序完成时退出, 它是通过使用守护线程和添加一个关闭钩子来等待他们完成。

 

addDelayedShutdownHook( ExecutorService service, long terminationTimeout, TimeUnit timeUnit):添加一个关闭的钩子来等待给定的ExecutorService中的线程完成。

 

getExitingExecutorService(ThreadPoolExecutor executor):将给定的ThreadPoolExecutor转换成ExecutorService实例,在程序完成时退出, 它是通过使用守护线程和添加一个关闭钩子来等待他们完成。

getExitingScheduledExecutorService( ScheduledThreadPoolExecutor executor):将给定的ThreadPoolExecutor转换成ScheduledExecutorService实例,在程序完成时退出, 它是通过使用守护线程和添加一个关闭钩子来等待他们完成。

 

sameThreadExecutor():创建一个ExecutorService实例,运行线程中的每一个任务。

 

listeningDecorator( ExecutorService delegate):创建一个ExecutorService实例,通过线程提交或者唤醒其他线程提交ListenableFutureTask到给定的ExecutorService实例。

listeningDecorator( ScheduledExecutorService delegate):创建一个ScheduledExecutorService实例,通过线程提交或者唤醒其他线程提交ListenableFutureTask到给定的ExecutorService实例。

 

platformThreadFactory():返回一个默认的线程工厂用于创建新的线程。

 

shutdownAndAwaitTermination( ExecutorService service, long timeout, TimeUnit unit):逐渐关闭指定的ExecutorService,首先会禁用新的提交, 然后会取消现有的任务。 

 

    来看下面一个典型示例:

int NUM_THREADS = 10;//10个线程
executorService =
        MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(NUM_THREADS));
ListenableFuture<String> listenableFuture =
        executorService.submit(new Callable<String>(){
            @Override
            public String call() throws Exception {
                return null;
            }
        });
listenableFuture.addListener(new Runnable() {
    @Override
    public void run() {
        //在Future任务完成之后运行的一些方法
        System.out.println("methodToRunOnFutureTaskCompletion");
    }
}, executorService);

    我们来对上面的代码做一个简单的解释:首先,我们使用ExecutorService实例创建了一个固定大小的线程池,然后我们将Callable对象提 交给ListeningExecutorService获取到我们需要的ListenableFuture实例,最后我们注册了一个回调函数在任务完成后 执行,值得注意的有一点,如果任务完成的时候我们设置回调方法,它将立即执行。

 

    不过,ListenableFuture. addListener有一个小的缺陷,我们没有办法接收返回的对象,这就导致在任务执行失败或成功的时候,我们不能执行其他的操作,不过Guava 提供了FutureCallback接口来弥补这个缺陷,下一篇:Guava库学习:学习Concurrency(四)FutureCallback,敬请期待...

 

    源码地址:http://git.oschina.net/realfighter/xx566-diary/blob/master/src/guava/ListenableFutureTest.java

转载于:https://my.oschina.net/realfighter/blog/349928

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值