【发布时间】:2017-04-11 15:15:44
【问题描述】:
我在使用 Guava RateLimiter 时遇到问题。我使用 RateLimiter.create(1.0) (“每秒 1 个许可”)创建 RateLimiter,并在每个周期调用 rateLimiter.acquire(),但是当我测试运行时,我得到以下结果:
Average: 1232.0 Diff since last: 2540
Average: 1180.0 Diff since last: 258
Average: 1159.0 Diff since last: 746
Average: 1151.0 Diff since last: 997
Average: 1144.0 Diff since last: 1004
Average 是它平均休眠的毫秒数,而 diff 是自上次打印以来经过的毫秒数。平均来说没关系,它不允许我的代码每秒运行超过一次。但有时(如您所见)它每秒运行一次以上。
你知道为什么吗?我错过了什么吗?
产生上述输出的代码:
private int numberOfRequests;
private Date start;
private long last;
private boolean first = true;
private void sleep() {
numberOfRequests++;
if(first) {
first = false;
start = new Date();
}
rateLimiter.acquire();
long current = new Date().getTime();
double num = (current -start.getTime()) / numberOfRequests;
System.out.println("Average: "+ num + " Diff since last: " + (current - last));
last = current;
}
【问题讨论】:
-
请发布生成此输出的代码的MCVE。
-
@AndyTurner 我已经用产生输出的代码更新了问题。
-
好的,马上跳出来的一件事是你不应该使用
System.getCurrentTimeMillis()(new Date()在内部使用)来测量经过的时间 - 请参阅 KevinB 的答案stackoverflow.com/a/1776053/3788176 - 你可以'实际上并不依赖于它单调增加。你应该改用System.nanoTime()。 -
code.google.com/p/guava-libraries/source/browse/guava/src/com/…RateLimiter使用的算法在源码中有相当详细的描述。
-
我明白了!感谢您指出时间问题。在其他项目中也很有用!我已经阅读了源代码,但没有找到问题的根源。会再试一次! @AndyTurner