减少主函数的等待时间,使得多任务能够异步非阻塞执行

ListenableFuture是可以监听的Future,它是对java原生Future的扩展增强。Future表示一个异步计算任务,当任务完成时可以得到计算结果。如果希望计算完成时马上就拿到结果展示给用户或者做另外的计算,就必须使用另一个线程不断的查询计算状态。这样做会使得代码复杂,且效率低下。如果使用ListenableFuture,Guava会帮助检测Future是否完成了,如果完成就自动调用回调函数,这样可以减少并发程序的复杂度。

1、MoreExecutors

该类是final类型的工具类,提供了很多静态方法。例如listeningDecorator方法初始化ListeningExecutorService方法,使用此实例submit方法即可初始化ListenableFuture对象。

2、ListeningExecutorService

该类是对ExecutorService的扩展,重写ExecutorService类中的submit方法,返回ListenableFuture对象。

3、ListenableFuture

该接口扩展了Future接口,增加了addListener方法,该方法在给定的excutor上注册一个监听器,当计算完成时会马上调用该监听器。不能够确保监听器执行的顺序,但可以在计算完成时确保马上被调用。

4、FutureCallback

该接口提供了OnSuccess和OnFailuren方法。获取异步计算的结果并回调。

5、Futures

该类提供和很多实用的静态方法以供使用。

6、ListenableFutureTask

该类扩展了FutureTask类并实现ListenableFuture接口,增加了addListener方法。

7、实例代码

package listenablefuture;

import com.google.common.util.concurrent.*;

import java.util.concurrent.*;

/**
* @author xfyou
* @date 2018/11/2
*/
public class ListenableFutureTest { private static final ThreadFactory THREAD_FACTORY = new ThreadFactoryBuilder().setDaemon(true).setNameFormat("test-pool-%d").build();
private static final ExecutorService EXECUTOR_SERVICE = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<>(false), THREAD_FACTORY);
private static final ListeningExecutorService SERVICE = MoreExecutors.listeningDecorator(EXECUTOR_SERVICE); public static void main(String[] args) {
// 可以无阻塞的实现多个任务的异步回调
for (int i = 0; i < 10; i++) {
ListenableFuture<Boolean> booleanTask = SERVICE.submit(new Callable<Boolean>() {
@Override
public Boolean call() {
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return true;
}
}); try {
// 使用get()方法会导致当前主线程一直阻塞直到异步线程的任务执行完成
System.out.println(booleanTask.get());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
} Futures.addCallback(booleanTask, new FutureCallback<Boolean>() {
@Override
public void onSuccess(Boolean result) {
System.out.println("BooleanTask: " + result);
} @Override
public void onFailure(Throwable t) {
}
}); ListenableFuture<String> stringTask = SERVICE.submit(new Callable<String>() {
@Override
public String call() {
return "Hello World";
}
});
Futures.addCallback(stringTask, new FutureCallback<String>() {
@Override
public void onSuccess(String result) {
System.out.println(result);
} @Override
public void onFailure(Throwable t) {
}
});
}
} }

Java future 和 Guava future的对比

Future 具有局限性。在实际应用中,当需要下载大量图片或视频时,可以使用多线程去下载,提交任务下载后,可以从多个Future中获取下载结果,由于Future获取任务结果是阻塞的,所以将会依次调用Future.get()方法,这样的效率会很低。很可能第一个下载速度很慢,则会拖累整个下载速度。

Future主要功能在于获取任务执行结果和对异步任务的控制。但如果要获取批量任务的执行结果,从上面的例子我们已经可以看到,单使用 Future 是很不方便的。其主要原因在于:一方面是没有好的方法去判断第一个完成的任务;另一方面是 Future的get方法 是阻塞的,使用不当会造成线程的浪费。第一个问题可以用 CompletionService 解决,CompletionService 提供了一个 take() 阻塞方法,用以依次获取所有已完成的任务。第二个问题可以用 Google Guava 库所提供的 ListeningExecutorService 和 ListenableFuture 来解决。除了获取批量任务执行结果时不便,Future另外一个不能做的事便是防止任务的重复提交。要做到这件事就需要 Future 最常见的一个实现类 FutureTask 了。Future只实现了异步,而没有实现回调,主线程get时会阻塞,可以轮询以便获取异步调用是否完成。

在实际的使用中建议使用Guava ListenableFuture来实现异步非阻塞,目的就是多任务异步执行,通过回调的方方式来获取执行结果而不需轮询任务状态。

 

Guava future的更多相关文章

  1. Future 异步回调 大起底之 Java Future 与 Guava Future

    目录 写在前面 1. Future模式异步回调大起底 1.1. 从泡茶的案例说起 1.2. 何为异步回调 1.2.1. 同步.异步.阻塞.非阻塞 1.2.2. 阻塞模式的泡茶案例图解 1.2.3. 回 ...

  2. java Future && Guava Future

    ### java future Runnable的任务是没有返回值,也不能抛出异常的java.util.concurrent.Callable接口,可以返回一个对象或者抛出异常 使用jdk的这种方式提 ...

  3. 从Java Future到Guava ListenableFuture实现异步调用

    原文地址: http://blog.csdn.net/pistolove/article/details/51232004 Java Future     通过Executors可以创建不同类似的线程 ...

  4. 从Java future 到 Guava ListenableFuture实现异步调用

    从Java future 到 Guava ListenableFuture实现异步调用 置顶 2016年04月24日 09:11:14 皮斯特劳沃 阅读数:17570 标签: java异步调用线程非阻 ...

  5. Guava 并行 Futures实例

    Future可以用来构建复杂的异步操作,方法不是返回一个值,而是一个Future对象.创建Future对象的过程(比如调用Future异步函数接口),不会阻塞当前线程操作,而且对象第一个次创建没有值, ...

  6. 同步、异步、阻塞、非阻塞与future

    前言 随着移动互联网的蓬勃发展,手机App层出不穷,其业务也随之变得错综复杂.针对于开发人员来说,可能之前的一个业务只需要调取一次第三方接口以获取数据,而如今随着需求的增加,该业务需调取多个不同的第三 ...

  7. 并发编程(三)Promise, Future 和 Callback

    并发编程(三)Promise, Future 和 Callback 异步操作的有两个经典接口:Future 和 Promise,其中的 Future 表示一个可能还没有实际完成的异步任务的结果,针对这 ...

  8. Java8 异步编排类CompletableFuture

    为了防止无良网站的爬虫抓取文章,特此标识,转载请注明文章出处.LaplaceDemon/ShiJiaqi. https://www.cnblogs.com/shijiaqi1066/p/8758206 ...

  9. [转载]Google Guava官方教程(中文版)

      原文链接  译文链接 译者: 沈义扬,罗立树,何一昕,武祖  校对:方腾飞 引言 Guava工程包含了若干被Google的 Java项目广泛依赖 的核心库,例如:集合 [collections] ...

随机推荐

  1. 6、Qt Project之音视频播放

    音视频播放  这里简单的制作了一个音乐播放器,播放器的界面设计如下所示: Step1:这里是界面对应的HTML文件: <?xml version="1.0" encoding ...

  2. HDU-1170的解题报告

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1170 题意:要求输入几个案例,每个案例包含操作符(+,-,*,/),操作数(两个整数).现在要求分别输 ...

  3. 大数据技术 - MapReduce的Combiner介绍

    本章来简单介绍下 Hadoop MapReduce 中的 Combiner.Combiner 是为了聚合数据而出现的,那为什么要聚合数据呢?因为我们知道 Shuffle 过程是消耗网络IO 和 磁盘I ...

  4. P3812 【模板】线性基

    P3812 [模板]线性基 理解 :线性基 类似于 向量的极大无关组,就是保持原来所有数的异或值的最小集合, 求解过程也类似,可以 O( 60 * n )的复杂度求出线性基,线性基有许多性质,例如 线 ...

  5. pyV8不支持dom操作,关于PyV8的支持DOM的疑问

    https://www.cnblogs.com/zdz8207/p/python_learn_note_123.html

  6. asp.net core下的如何给网站做安全设置

    首先,我们来看下stack overflow网站的请求头文件: 可以看到一些我们熟悉或是陌生的HTTP头部文件字段.在这里我们在对HTTP输入流的头部文件中,做一些基本的防护.首先要明确,既然我们是对 ...

  7. XamarinAndroid组件教程RecylerView适配器动画动画种类

    XamarinAndroid组件教程RecylerView适配器动画动画种类 本节将讲解RecylerView适配器动画,其中包含动画种类和如何使用动画. 动画种类 RecylerViewAnimat ...

  8. nginx那些事儿

    一.mac上安装nginx brew install nginx # 核心安装目录,启动文件在该目录的bin下面,欢迎页面在html下面. /usr/local/Cellar/nginx/1.12.2 ...

  9. HOJ3237----BFS/DFS

    /* 注意两点 . 不可以使用替换可用节点为不可用节点的方法进行DFS 因为角落也可能有油,替换了就出不来.(某学长指导) . 可用通过开一个数组(例如我的b[][]数组) 用了存储到当前位置剩余最大 ...

  10. 2554 ACM 杭电 数学

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=2554 中文题目,题意易懂.但是本题涉及到很强的数学思维. 思路:看了题意后:我的第一反应是除了 n=1,n ...