使用Guava RateLimiter实现java流量控制
2019-11-18 本文已影响0人
昆猪IMK
Guava 是一个由Google开发的java类库集合的扩展项目,基于目前被广泛应用的java1.6,这些高质量的API提供了强大的扩展功能, 并使你的java代码更加优雅,更加简洁。本文使用Guava concurrent包下的RateLimiter类实现流量控制功能。
在介绍RateLimiter之前,先看看java自带的Semaphore类。
Semaphore位于java.Util.concurrent下,可用于控制并发,在创建Semaphore对象时,可指定并发数,线程开始时调用acquire方法,同时当前可用并发数量减1,线程当并发量达到指定的并发数,即可用并发为0时,线程等待。
以下是一个使用Semaphore实现并发控制的简单例子:
import java.util.concurrent.Semaphore;
public class SemaphoreTest {
public static void main(String[] args) {
Test t = new Test();
for (int i = 0; i < 5; i++) {
new Thread(() -> {
t.print();
}).start();
}
}
}
class Test {
private static final Semaphore sp = new Semaphore(3);
public void print() {
try {
sp.acquire();
System.out.println(Thread.currentThread().getName()+" started: "+sp.availablePermits());
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
sp.release();
System.out.println(Thread.currentThread().getName()+" released: "+sp.availablePermits());
}
}
}
了解了Semaphore的使用方法后,再看下RateLimiter的使用,其实两者的使用方式是非常相似的,但是值得注意的是,Semaphore限定了并发数,而RateLimiter限定的是单位时间内的并发数,即并发的速率。
以下是一个使用RateLimiter实现并发控制的简单例子,每秒并发数设定为1,读者可以比较上面Semaphore的代码感受区别。
import com.google.common.util.concurrent.RateLimiter;
public class RateLimiterTest {
public static void main(String[] args){
TestMethods tm = new TestMethods();
for(int i=0;i<5;i++){
new Thread(()->{
tm.print();
}).start();
}
}
}
class TestMethods{
public void print(){
try {
Constants.rl.acquire();
System.out.println("Thread: "+Thread.currentThread().getName()+"RateLimiter: "+Constants.rl.getRate());
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class Constants{
public static final RateLimiter rl = RateLimiter.create(1.0);
}