zoukankan      html  css  js  c++  java
  • 021 ListenableFuture

    一 .概述

      在jdk之中,在1.5之后出现了Future接口,这个接口可以帮助我们完成异步任务结构的获取.

      我们首先看下接口的定义:

    public interface Future<V> {
        // 取消任务
        boolean cancel(boolean mayInterruptIfRunning);
        // 判断任务是否被删除掉
        boolean isCancelled();
        // 判断任务是否完成
        boolean isDone();
        // 获取数据
        V get() throws InterruptedException, ExecutionException;
        // 给出指定的时间,获取数据
        V get(long timeout, TimeUnit unit)
            throws InterruptedException, ExecutionException, TimeoutException;
    }

    但是这个接口存在一个问题,就是在获取数据的时候一旦任务没有完成就会阻塞该方法.

      这样在一定的程度上,对并发的效果就是一种削弱.

    在guava之中,出现了一种事件回调的方式,当我们的线程获取到执行的结果之后,就会自动帮助我们回调方法,这样就减少了我们对Future结构获取数据的阻塞.

    public interface ListenableFuture<V> extends Future<V> {
     
      void addListener(Runnable listener, Executor executor);
    }

    通过上面的定义,我们ListenableFuture实际上继承了Future接口,并且添加了一个监听器,通过这种方式,我们就可以指定对应的回调.

    通过调用ListenableFuture.addListener方法完成这个功能,这个方法使用Runnable实例和ExecutorService对象,ExecutorService可以是初始任务提交的相同Executor实例,或者完全是另外一个ExecutorService实例。

    那么,我们怎么创建ListenableFuture对象呢?

      我们知道,Future对象一般情况下是由线程执行器对象通过submit()方法提交获得,而ListenableFuture就是通过一个包装的线程执行器创建出来的.

    看下面的例子:  

    public class ListenableFutureTest {
    
        public static void main(String[] args) {
            // 使用MoreExecutors包装器包装一个基本的Executor对象,我们就能获取到一个ListeningExecutorService对象
            ListeningExecutorService executorService = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(2));
            ListenableFuture<String> listenableFuture = executorService.submit(new Callable<String>() {
    
                @Override
                public String call() throws Exception {
                    TimeUnit.SECONDS.sleep(3);
                    return "trek";
                }
                
            });
            
            // 添加回调
            listenableFuture.addListener(new Runnable() {
                @Override
                public void run() {
                    System.out.println("执行了回调的方法");
                    executorService.shutdown();
                }
            }, executorService);
            
            System.out.println("主线程执行完毕");
        }
    }

    我们可以发现存在一个问题,那就是我们无法从ListenableFuture之中获取线程任务执行的结果.但是我们可以在线程任务执行完之后,进行另外一个线程任务的回调.

      

  • 相关阅读:
    今天面试一些程序员(新,老)手的体会
    UVA 10635 Prince and Princess
    poj 2240 Arbitrage
    poj 2253 Frogger
    poj 2485 Highways
    UVA 11258 String Partition
    UVA 11151 Longest Palindrome
    poj 1125 Stockbroker Grapevine
    poj 1789 Truck History
    poj 3259 Wormholes
  • 原文地址:https://www.cnblogs.com/trekxu/p/10332686.html
Copyright © 2011-2022 走看看