先看下demo
//1秒通过0.5个
RateLimiter rateLimiter=RateLimiter.create(0.5);
for(int i=0;i<10;i++){
rateLimiter.acquire();
System.out.println(new Date()+" "+i);
if (!rateLimiter.tryAcquire(1000, TimeUnit.MILLISECONDS)) {
System.out.println("短期无法获取令牌,真不幸,排队也瞎排");
}
}
RateLimiter.create(0.5);这个是配置2秒通过1个。
执行结果
可以看出2秒执行一次。
而rateLimiter.tryAcquire(1000, TimeUnit.MILLISECONDS)
是在1秒内是否能获取到令牌token,不能的话返回false
如果并发去查询呢?
import com.google.common.util.concurrent.RateLimiter;
import java.util.Date;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
public class test3 {
//1秒通过0.5个
static final RateLimiter rateLimiter=RateLimiter.create(0.5);
public static void main(String[] args) {
final CountDownLatch countDownLatch = new CountDownLatch(100);
for(int i=0;i<100;i++){
countDownLatch.countDown();
new Thread(new Runnable() {
public void run() {
aaa();
}
}).start();
/*try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}*/
}
}
static final public void aaa(){
// for(int i=0;i<10;i++){
rateLimiter.acquire();
// System.out.println(new Date()+" "+i);
System.out.println(new Date());
/*if (!rateLimiter.tryAcquire(1000, TimeUnit.MILLISECONDS)) {
System.out.println("短期无法获取令牌,真不幸,排队也瞎排");
}*/
// }
}
}
执行结果
即使线程是并发访问的,但是还是被限流了