// 限流器流速:2请求/秒
RateLimiter limiter = RateLimiter.create(2.0);
ExecutorService pool = Executors.newFixedThreadPool(1);
final long[] prev = {System.nanoTime()};
for (int i = 0; i < 20; i++) {
// 限流器限流
limiter.acquire();
pool.execute(() -> {
long cur = System.nanoTime();
System.out.println((cur - prev[0]) / 1000_000);
prev[0] = cur;
});
}
// 输出
// 499
// 499
// 497
// 502
// 496
public class SimpleLimiter {
// 令牌发放间隔
private static final long INTERVAL = 1000_000_000;
// 下一令牌发放时间
private long next = System.nanoTime();
// 预占令牌,返回能够获取令牌的时间
private synchronized long reserve(long now) {
if (now > next) {
// 请求时间在下一令牌产生时间之后
// 重新计算下一令牌产生时间
next = now;
}
// 能够获取令牌的时间
long at = next;
// 更新下一个令牌产生的时间
next += INTERVAL;
// 返回线程需要等待的时间
return Math.max(at, 0L);
}
// 申请令牌
public void acquire() {
long now = System.nanoTime();
// 预占令牌
long at = reserve(now);
long waitTime = Math.max(at - now, 0);
if (waitTime > 0) {
try {
TimeUnit.NANOSECONDS.sleep(waitTime);
} catch (InterruptedException ignored) {
}
}
}
}
转载请注明出处:http://zhongmingmao.me/2019/05/27/java-concurrent-guava-rate-limiter/
访问原文「 Java并发 -- Guava RateLimiter 」获取最佳阅读体验并参与讨论