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之中获取线程任务执行的结果.但是我们可以在线程任务执行完之后,进行另外一个线程任务的回调.

      

  • 相关阅读:
    .net面试题目问答题2
    .net面试题目问答题1
    .net面试题目101-130
    .net面试题目51-100
    .net面试题目1-50
    试题
    2014奇虎360研发类校园招聘面试题分享
    JAVA基础
    JAVA中集合的继承关系
    美团
  • 原文地址:https://www.cnblogs.com/trekxu/p/10332686.html
Copyright © 2011-2022 走看看