我有限制调用100 / s的情况。
我正在考虑使用Google Guava RateLimiter。我测试了这样: -
int cps = 100;
RateLimiter limiter = RateLimiter.create(cps);
for(int i=0;i<200;i++) {
limiter.acquire();
System.out.print("\rNumber of records processed = " + i+1);
}
但是代码没有停在100条记录上,让1秒完成。我做错了吗?
答案 0 :(得分:5)
RateLimiter工作正常。问题是您的输出是缓冲的,因为您每次都不会刷新它。通常,标准输出是行缓冲的。所以,如果你写了
System.out.println("Number of records processed = " + (i+1));
你会看到100暂停。但是,你有什么:
System.out.print(&#34; \ r \ n已处理的记录数量=&#34; + i + 1);
有两个问题。首先,&#34; \ r&#34;不被视为新线,不会引起潮红;因此整个输出都被缓冲并一次性打印到控制台。其次,你需要把(i + 1)括在括号中。你将i追加到字符串中,然后将1附加到结果字符串。
答案 1 :(得分:2)
除了@ DodgyCodeException关于输出刷新和连接+1
的建议之外,让我们运行此代码以确保您了解RateLimiter
的工作原理:
final double permitsPerSecond = 1;
RateLimiter limiter = RateLimiter.create(permitsPerSecond);
final Stopwatch stopwatch = Stopwatch.createStarted();
int i = 0;
for (; i < 2 * permitsPerSecond; i++) {
limiter.acquire();
}
System.out.println("Elapsed = " + stopwatch.stop().elapsed(TimeUnit.MILLISECONDS) + "ms");
System.out.println("Number of records processed = " + i);
(请注意,我将尝试次数设置为permitsPerSecond
次数的两倍。)当您将permitsPerSecond
设置为1
时,您会看到:
经过= 1001ms
处理的记录数= 2
对于permitsPerSecond = 10;
和permitsPerSecond = 100;
,它接近(在数学意义上)2s限制,因为第11或第101次尝试等待RateLimiter
中设置的限制:
Elapsed = 1902ms
处理的记录数= 20
和
Elapsed = 1991ms
处理的记录数= 200