文档章节

Guava并发:ListenableFuture与RateLimiter示例

cloud-coder
 cloud-coder
发布于 2014/12/23 14:52
字数 684
阅读 10473
收藏 103

概念

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

        推荐使用第二种方法,因为第二种方法可以直接得到Future的返回值,或者处理错误情况。本质上第二种方法是通过调动第一种方法实现的,做了进一步的封装。

另外ListenableFuture还有其他几种内置实现:

  1. SettableFuture:不需要实现一个方法来计算返回值,而只需要返回一个固定值来做为返回值,可以通过程序设置此Future的返回值或者异常信息

  2. CheckedFuture: 这是一个继承自ListenableFuture接口,他提供了checkedGet()方法,此方法在Future执行发生异常时,可以抛出指定类型的异常。


    RateLimiter类似于JDK的信号量Semphore,他用来限制对资源并发访问的线程数,本文介绍RateLimiter使用

代码示例

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

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 com.google.common.util.concurrent.RateLimiter;

public class ListenableFutureDemo {
	public static void main(String[] args) {
		testRateLimiter();
		testListenableFuture();
	}

	/**
	 * RateLimiter类似于JDK的信号量Semphore,他用来限制对资源并发访问的线程数
	 */
	public static void testRateLimiter() {
		ListeningExecutorService executorService = MoreExecutors
				.listeningDecorator(Executors.newCachedThreadPool());

		RateLimiter limiter = RateLimiter.create(5.0); // 每秒不超过4个任务被提交

		for (int i = 0; i < 10; i++) {
			limiter.acquire(); // 请求RateLimiter, 超过permits会被阻塞

			final ListenableFuture<Integer> listenableFuture = executorService
					.submit(new Task("is "+ i));
		}
	}

	public static void testListenableFuture() {
		ListeningExecutorService executorService = MoreExecutors
				.listeningDecorator(Executors.newCachedThreadPool());

		final ListenableFuture<Integer> listenableFuture = executorService
				.submit(new Task("testListenableFuture"));

		
		//同步获取调用结果
		try {
			System.out.println(listenableFuture.get());
		} catch (InterruptedException e1) {
			e1.printStackTrace();
		} catch (ExecutionException e1) {
			e1.printStackTrace();
		}
		
		//第一种方式
		listenableFuture.addListener(new Runnable() {
			@Override
			public void run() {
				try {
					System.out.println("get listenable future's result "
							+ listenableFuture.get());
				} catch (InterruptedException e) {
					e.printStackTrace();
				} catch (ExecutionException e) {
					e.printStackTrace();
				}
			}
		}, executorService);

		//第二种方式
		Futures.addCallback(listenableFuture, new FutureCallback<Integer>() {
			@Override
			public void onSuccess(Integer result) {
				System.out
						.println("get listenable future's result with callback "
								+ result);
			}

			@Override
			public void onFailure(Throwable t) {
				t.printStackTrace();
			}
		});
	}
}

class Task implements Callable<Integer> {
	String str;
	public Task(String str){
		this.str = str;
	}
	@Override
	public Integer call() throws Exception {
		System.out.println("call execute.." + str);
		TimeUnit.SECONDS.sleep(1);
		return 7;
	}
}

Guava版本

<dependency>
			<groupId>com.google.guava</groupId>
			<artifactId>guava</artifactId>
			<version>14.0.1</version>
		</dependency>

© 著作权归作者所有

cloud-coder
粉丝 247
博文 193
码字总数 141277
作品 0
广州
架构师
私信 提问
加载中

评论(2)

程序猿Zz
Guava很强大
_凤求凰_
_凤求凰_
写的不错。
Guava 27.0 发布,Google 的 Java 核心工具库

Guava 27.0 发布了,Guava 是 Google 的一个开源项目,包含许多 Google 核心 Java 常用库,如:集合 [collections] 、缓存 [caching] 、原生类型支持 [primitives support] 、并发库 [concu...

h4cd
2018/10/19
3.1K
4
Guava - 并行编程Futures

Guava为Java并行编程Future提供了很多有用扩展,其主要接口为ListenableFuture,并借助于Futures静态扩展。 继承至Future的ListenableFuture,允许我们添加回调函数在线程运算完成时返回值或...

zting科技
2017/01/10
0
0
【Guava】使用Guava的RateLimiter做限流

一、常见的限流算法 目前常用的限流算法有两个:漏桶算法和令牌桶算法。 1.漏桶算法 漏桶算法的原理比较简单,请求进入到漏桶中,漏桶以一定的速率漏水。当请求过多时,水直接溢出。可以看出...

大海201506
2018/09/19
200
0
数据库分库分表中间件 Sharding-JDBC 源码分析 —— SQL 执行

摘要: 原创出处 http://www.iocoder.cn/Sharding-JDBC/sql-execute/ 「芋道源码」欢迎转载,保留摘要,谢谢! 本文主要基于 Sharding-JDBC 1.5.0 正式版 1. 概述 2. ExecutorEngine 3. Execu...

芋艿V
2017/10/08
0
0
数据库分库分表中间件 Sharding-JDBC 源码分析 —— SQL 执行

摘要: 原创出处 www.iocoder.cn/Sharding-JD… 「芋道源码」欢迎转载,保留摘要,谢谢! 本文主要基于 Sharding-JDBC 1.5.0 正式版 1. 概述 2. ExecutorEngine 2.1 ListeningExecutorService...

芋道源码掘金Java群217878901
2017/10/08
0
0

没有更多内容

加载失败,请刷新页面

加载更多

方法重载和重写是什么?有什么区别?

重写:在子类中将父类的成员方法的名称保留,重新编写成员方法的实现内容,更改方法的访问权限,修改返回类型的为父类返回类型的子类。 一些规则: 重写发生在子类继承父类 参数列表必须完全...

ConstXiong
13分钟前
2
0
Spring-Framework 目录

ls spring-orm/src/main/java/org/springframework/orm/hibernate5/ ObjectRetrievalFailureException.java jpa/ ......

MtrS
31分钟前
3
0
大学慕课

Visual C,Turbo C,Dev C的关系 不管是 Visual C、Turbo C 还是 Dev C,本质都是C语言,不存在高下之分。 三种叫法不同是因为 C 语言在三种不同的开发环境中拥有一些不同的开发习惯的区别。...

电子197徐泽彬
50分钟前
3
0
GC偏方 强行fullgc

转自 https://www.jianshu.com/p/be5389ca93f7 FullGC这么恐怖,有办法缓解么,或者说尽量避免它在白天,甚至业务高峰期出现?有!笔者给你分享一个歪门邪道,不记得是多少年前,在哪里道听途...

os_m
54分钟前
4
0
源码分析Mybatis MappedStatement的创建流程

上文源码分析Mybatis MapperProxy创建流程重点阐述 MapperProxy 的创建流程,但并没有介绍 *.Mapper.java(UserMapper.java) 是如何与 *Mapper.xml 文件中的 SQL 语句是如何建立关联的。本文将...

中间件兴趣圈
今天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部