Guava并发:ListenableFuture与RateLimiter示例

开发 后端
ListenableFuture顾名思义就是可以监听的Future,它是对java原生Future的扩展增强 RateLimiter类似于JDK的信号量Semphore,他用来限制对资源并发访问的线程数,本文介绍RateLimiter使用。

概念

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

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

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

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

 

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

 

 

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

代码示例

  1. import java.util.concurrent.Callable;  
  2. import java.util.concurrent.ExecutionException;  
  3. import java.util.concurrent.Executors;  
  4. import java.util.concurrent.TimeUnit;  
  5.    
  6. import com.google.common.util.concurrent.FutureCallback;  
  7. import com.google.common.util.concurrent.Futures;  
  8. import com.google.common.util.concurrent.ListenableFuture;  
  9. import com.google.common.util.concurrent.ListeningExecutorService;  
  10. import com.google.common.util.concurrent.MoreExecutors;  
  11. import com.google.common.util.concurrent.RateLimiter;  
  12.    
  13. public class ListenableFutureDemo {  
  14.     public static void main(String[] args) {  
  15.         testRateLimiter();  
  16.         testListenableFuture();  
  17.     }  
  18.    
  19.     /**  
  20.      * RateLimiter类似于JDK的信号量Semphore,他用来限制对资源并发访问的线程数  
  21.      */ 
  22.     public static void testRateLimiter() {  
  23.         ListeningExecutorService executorService = MoreExecutors  
  24.                 .listeningDecorator(Executors.newCachedThreadPool());  
  25.    
  26.         RateLimiter limiter = RateLimiter.create(5.0); // 每秒不超过4个任务被提交  
  27.    
  28.         for (int i = 0; i < 10; i++) {  
  29.             limiter.acquire(); // 请求RateLimiter, 超过permits会被阻塞  
  30.    
  31.             final ListenableFuture<Integer> listenableFuture = executorService  
  32.                     .submit(new Task("is "+ i));  
  33.         }  
  34.     }  
  35.    
  36.     public static void testListenableFuture() {  
  37.         ListeningExecutorService executorService = MoreExecutors  
  38.                 .listeningDecorator(Executors.newCachedThreadPool());  
  39.    
  40.         final ListenableFuture<Integer> listenableFuture = executorService  
  41.                 .submit(new Task("testListenableFuture"));  
  42.    
  43.            
  44.         //同步获取调用结果  
  45.         try {  
  46.             System.out.println(listenableFuture.get());  
  47.         } catch (InterruptedException e1) {  
  48.             e1.printStackTrace();  
  49.         } catch (ExecutionException e1) {  
  50.             e1.printStackTrace();  
  51.         }  
  52.            
  53.         //***种方式  
  54.         listenableFuture.addListener(new Runnable() {  
  55.             @Override 
  56.             public void run() {  
  57.                 try {  
  58.                     System.out.println("get listenable future's result " 
  59.                             + listenableFuture.get());  
  60.                 } catch (InterruptedException e) {  
  61.                     e.printStackTrace();  
  62.                 } catch (ExecutionException e) {  
  63.                     e.printStackTrace();  
  64.                 }  
  65.             }  
  66.         }, executorService);  
  67.    
  68.         //第二种方式  
  69.         Futures.addCallback(listenableFuture, new FutureCallback<Integer>() {  
  70.             @Override 
  71.             public void onSuccess(Integer result) {  
  72.                 System.out  
  73.                         .println("get listenable future's result with callback " 
  74.                                 + result);  
  75.             }  
  76.    
  77.             @Override 
  78.             public void onFailure(Throwable t) {  
  79.                 t.printStackTrace();  
  80.             }  
  81.         });  
  82.     }  
  83. }  
  84.    
  85. class Task implements Callable<Integer> {  
  86.     String str;  
  87.     public Task(String str){  
  88.         this.str = str;  
  89.     }  
  90.     @Override 
  91.     public Integer call() throws Exception {  
  92.         System.out.println("call execute.." + str);  
  93.         TimeUnit.SECONDS.sleep(1);  
  94.         return 7;  
  95.     }  

Guava版本

  1. <dependency> 
  2.             <groupId>com.google.guava</groupId> 
  3.             <artifactId>guava</artifactId> 
  4.             <version>14.0.1</version> 
  5.         </dependency> 

本文出自:http://my.oschina.net/cloudcoder/blog/359598

责任编辑:林师授 来源: oschina
相关推荐

2022-06-22 09:07:09

Guava算法

2024-01-31 08:50:41

Guava并发工具

2021-05-21 12:36:16

限流代码Java

2023-10-31 07:52:10

2021-06-09 11:41:10

RateLimiterJava代码

2021-05-31 07:01:46

限流算法令牌

2009-07-03 17:44:06

JSP介绍

2009-07-09 16:22:12

WebWork配置

2021-06-07 17:51:29

并发高并发编程

2023-07-06 08:06:47

LockCondition公平锁

2023-01-15 17:24:16

LinuxBSDwhereis 命令

2023-01-10 14:10:27

Linuxwho 命令

2023-01-12 13:32:00

w 命令Linux

2023-02-14 16:45:54

2022-09-21 08:16:18

缓存框架

2021-07-30 07:28:15

WorkerPoolGo语言

2023-10-23 10:48:30

Golang数组

2010-07-15 15:56:46

AIX TELNET命

2023-03-28 09:58:56

Python变量

2018-11-16 15:35:10

Spring事务Java
点赞
收藏

51CTO技术栈公众号