ListenableFuture的说明

  并发编程是一个难题,但是一个强大而简单的抽象可以显著的简化并发的编写。出于这样的考虑,Guava 定义了 ListenableFuture接口并继承了JDK concurrent包下的Future 接口,ListenableFuture 允许你注册回调方法(callbacks),在运算(多线程执行)完成的时候进行调用,  或者在运算(多线程执行)完成后立即执行。这样简单的改进,使得可以明显的支持更多的操作,这样的功能在JDK concurrent中的Future是不支持的。 在高并发并且需要大量Future对象的情况下,推荐尽量使用ListenableFuture来代替..

  ListenableFuture 中的基础方法是addListener(Runnable, Executor), 该方法会在多线程运算完的时候,在Executor中执行指定的Runnable。

ListenableFuture的创建和使用

  对应JDK中的 ExecutorService.submit(Callable) 提交多线程异步运算的方式,Guava 提供了ListeningExecutorService 接口, 该接口返回 ListenableFuture, 而相应的ExecutorService 返回普通的 Future。将 ExecutorService 转为 ListeningExecutorService,可以使用MoreExecutors.listeningDecorator(ExecutorService)进行装饰。举例说明:

  

ListeningExecutorService pool = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(10));

然后我们可以向这个ListeningExecutorService提交Callable任务

final ListenableFuture<String> future =  pool.submit(new Callable<String>() {
@Override
public String call() throws Exception {
Thread.sleep(1000*3);
return "Task done !";
}
});

然后我们添加Listener:

future.addListener(new Runnable() {
@Override
public void run() {
try {
final String contents = future.get();
System.out.println(contents);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}, MoreExecutors.sameThreadExecutor());

我们看看上面的代码,确实不怎么优雅,我们需要处理抛出的异常,需要自己通过future.get()获得前面计算的值。有没有更加简便的方法呢?当然有,Guava提供了一个简便方法来替代上面的写法:

Futures.addCallback(future, new FutureCallback<String>() {
@Override
public void onSuccess(String result) {
System.out.println(result);
} @Override
public void onFailure(Throwable t) {
t.printStackTrace();
}
});

完成代码如下:

package concurrency;

import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors; import java.util.concurrent.Callable;
import java.util.concurrent.Executors; /**
* Created by hupeng on 2014/9/24.
*/
public class ListenableFutureTest { public static void main(String[] args) throws InterruptedException {
ListeningExecutorService pool = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(10)); final ListenableFuture<String> future = pool.submit(new Callable<String>() {
@Override
public String call() throws Exception {
Thread.sleep(1000 * 2);
return "Task done !";
}
}); // future.addListener(new Runnable() {
// @Override
// public void run() {
// try {
// final String contents = future.get();
// System.out.println(contents);
// } catch (InterruptedException e) {
// e.printStackTrace();
// } catch (ExecutionException e) {
// e.printStackTrace();
// }
// }
// }, MoreExecutors.sameThreadExecutor()); Futures.addCallback(future, new FutureCallback<String>() {
@Override
public void onSuccess(String result) {
System.out.println(result);
} @Override
public void onFailure(Throwable t) {
t.printStackTrace();
}
}); Thread.sleep(5 * 1000); //wait for task done pool.shutdown();
}
}

Java 异步转同步 ListenableFuture in Guava的更多相关文章

  1. Java异步转同步

    参考原文: <http://blog.csdn.net/veson__/article/details/53898890>

  2. java 异步查询转同步多种实现方式:循环等待,CountDownLatch,Spring EventListener,超时处理和空循环性能优化

    异步转同步 业务需求 有些接口查询反馈结果是异步返回的,无法立刻获取查询结果. 正常处理逻辑 触发异步操作,然后传递一个唯一标识. 等到异步结果返回,根据传入的唯一标识,匹配此次结果. 如何转换为同步 ...

  3. 5种必会的Java异步调用转同步的方法你会几种

    转载请注明本文地址:https://www.jianshu.com/p/f00aa6f66281 源码地址:https://gitee.com/sunnymore/asyncToSync Sunny先 ...

  4. Java并发(二)异步转同步

    目录 前置条件:构造一个异步调用 一.使用wait和notify方法 二.使用条件锁 三.Future 四.使用CountDownLatch 五.使用CyclicBarrier 总结 在Java并发编 ...

  5. java 异步机制与同步机制的区别

    所谓异步输入输出机制,是指在进行输入输出处理时,不必等到输入输出处理完毕才返回.所以异步的同义语是非阻塞(None Blocking). 网上有很多网友用很通俗的比喻  把同步和异步讲解的很透彻 转过 ...

  6. Java异步调用转同步的5种方式

    1.异步和同步的概念 同步调用:调用方在调用过程中,持续等待返回结果. 异步调用:调用方在调用过程中,不直接等待返回结果,而是执行其他任务,结果返回形式通常为回调函数. 2 .异步转为同步的概率 需要 ...

  7. Java 异步编程 (5 种异步实现方式详解)

    ​ 同步操作如果遇到一个耗时的方法,需要阻塞等待,那么我们有没有办法解决呢?让它异步执行,下面我会详解异步及实现@mikechen 目录 什么是异步? 一.线程异步 二.Future异步 三.Comp ...

  8. java异步编程降低延迟

    目录 java异步编程降低延迟 一.ExecutorService和CompletionService 二.CompletableFuture(重要) 三.stream中的parallel(并行流) ...

  9. ListenableFuture in Guava

    ListenableFuture的说明 并发编程是一个难题,但是一个强大而简单的抽象可以显著的简化并发的编写.出于这样的考虑,Guava 定义了 ListenableFuture接口并继承了JDK c ...

随机推荐

  1. 基于CXF搭建webService

    1.导入相关jar包,具体哪些包我记不太清了 2.在applicationContext中加入相关配置信息,如下所示: <beans xmlns="http://www.springf ...

  2. 努比亚 Z17s (Nubia NX595J) 解锁BootLoader 并刷入recovery ROOT

    首先下载好工具链接:https://pan.baidu.com/s/1nw7BoZB 密码:zuun 备用下载链接:https://pan.baidu.com/s/1c3mUQGg 本篇教程教你如何傻 ...

  3. Burn Down Chart(2018.5.28~2018.6.3)

    任务安排 (2018.6.2 更新——前端总进度) (2018.6.3 更新——后端燃尽图) 娄雨禛[前端部分] 曾子轩[后端部分+燃尽图] 前端 齐天扬+刘鼎乾:设计两组页面,只要求框架和简单的 c ...

  4. 解决无法移除tomcat中的项目

    问题:启动myeclipse,tomcat提示报错,blind,但是你移除的时候无法移除,只会显示一个黄色的感叹号,此时你直接在webapp中删除时,也提示呗占用无法删除. 办法:关掉myeclips ...

  5. java 练习

    class Hello{ public static void main(String [] args) { System.out.println(" Hello 这是我的第一个java作品 ...

  6. WEB笔记-2 剖析CSS规则

    2.1 剖析CSS规则   规则即指令,其声明了需要修改的元素及要应用给元素的样式.     2.2 为文档添加样式的三种方法   行内样式:直接写在HTML文档标签中的style属性当中,行内元素只 ...

  7. Docker 数据卷重复挂载测试

    没想到一年没写博客了,这中间都是记在自己的笔记本上,大部分网上都有,这个好像没有,所以发上来吧! 本文是测试Docker容器(相同目录/父子目录)同时挂载到宿主机(同目录/不同目录)时的情况,废话少说 ...

  8. 连接(JOIN)运算

    内连接--INNER JOIN 此处用商品表(product)和商店商品表(ShopProduct)测试,外键:product_id select sp.shop_id, sp.shop_name, ...

  9. Ubuntu 更换阿里源

    查看新版本信息 lsb_release -c Ubuntu 12.04 (LTS)代号为precise. Ubuntu 14.04 (LTS)代号为trusty. Ubuntu 15.04 代号为vi ...

  10. Day 2 语言元素

    1.变量和类型 在程序设计中,变量是一种存储数据的载体.计算机中的变量是实际存在的数据或者说是存储器中存储数据的一块内存空间,变量的值可以被读取和修改,这是所有计算和控制的基础.计算机能处理的数据有很 ...