案例一
packagecom.mmall.concurrency.example.rateLimiter; importcom.google.common.util.concurrent.RateLimiter; importlombok.extern.slf4j.Slf4j; importjava.util.concurrent.TimeUnit; publicclassRateLimiterExample1 { // 因为创建的时候规定 1 秒 5 个令牌,即换算成 1 个令牌 200 毫秒。privatestaticRateLimiterrateLimiter=RateLimiter.create(5); publicstaticvoidmain(String[] args) throwsException { for (intindex=0; index<100; index++) { if (rateLimiter.tryAcquire(190, TimeUnit.MILLISECONDS)) { handle(index); } } } privatestaticvoidhandle(inti) { log.info("{}", i); } }
分析
tryAcquire:在规定时间内(n ms),如果时间赶不上,则该次阻塞将被丢弃,所以可能会产生一个都没有输出或部分输出。
- 当 n > 200,可以输出全部
- 当 n == 200,可以输出部分
- 当 n < 200,一个都没有
案例二
packagecom.mmall.concurrency.example.rateLimiter; importcom.google.common.util.concurrent.RateLimiter; importlombok.extern.slf4j.Slf4j; importjava.util.concurrent.TimeUnit; publicclassRateLimiterExample2 { privatestaticRateLimiterrateLimiter=RateLimiter.create(5); publicstaticvoidmain(String[] args) throwsException { for (intindex=0; index<100; index++) { rateLimiter.acquire(); handle(index); } } privatestaticvoidhandle(inti) { log.info("{}", i); } }
// 输出18:04:03.190 [main] INFOc.m.c.example.rateLimiter.test9-018:04:03.387 [main] INFOc.m.c.example.rateLimiter.test9-118:04:03.587 [main] INFOc.m.c.example.rateLimiter.test9-218:04:03.787 [main] INFOc.m.c.example.rateLimiter.test9-318:04:03.988 [main] INFOc.m.c.example.rateLimiter.test9-418:04:04.188 [main] INFOc.m.c.example.rateLimiter.test9-518:04:04.388 [main] INFOc.m.c.example.rateLimiter.test9-618:04:04.588 [main] INFOc.m.c.example.rateLimiter.test9-718:04:04.789 [main] INFOc.m.c.example.rateLimiter.test9-818:04:04.988 [main] INFOc.m.c.example.rateLimiter.test9-9...
分析
- 根据输出也可以看到 acquire 方法 1s 正常获取 5 个令牌,符合题意。