1、简介
RateLimiter是guava提供的基于令牌桶算法的实现类,可以非常简单的完成限流特技。
2、引入依赖
<!-- guava 限流 -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>25.1-jre</version>
</dependency>
3、demo
rateLimiter.acquire()该方法会阻塞线程,直到令牌桶中能取到令牌为止才继续向下执行,并返回等待的时间。
import com.google.common.util.concurrent.RateLimiter;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Demo {
public static void main(String[] args) {
//一秒最多生成0.5个令牌
RateLimiter rateLimiter = RateLimiter.create(0.5);
List<Runnable> tasks = new ArrayList<Runnable>();
for (int i = 0; i < 10; i++) {
tasks.add(new UserRequest(i));
}
ExecutorService threadPool = Executors.newCachedThreadPool();
for (Runnable runnable : tasks) {
System.out.println("等待时间:" + rateLimiter.acquire());
threadPool.execute(runnable);
}
}
private static class UserRequest implements Runnable {
private int id;
public UserRequest(int id) {
this.id = id;
}
public void run() {
System.out.println(id);
}
}
}
5、实际限流场景
tryAcquire(long timeout, TimeUnit unit)方法,指定一个超时时间,一旦判断出在timeout时间内还无法取得令牌,就返回false。
Boolean flag = rateLimiter.tryAcquire();
f(flag){
//todo
}
else{
return;
}