// 限流器流速: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 」获取最佳阅读体验并参与讨论