【发布时间】:2016-12-04 17:12:09
【问题描述】:
我正在编写一个算法来接收消息,然后确定它们是否符合既定的消息传递速率。
例如,在任何 50 秒的窗口中发送的消息不超过 5 条。因此,此窗口必须是滚动窗口。
我已经从this post. 实现了这个令牌桶算法但是,我无法让它始终如一地工作。它通过了一些测试用例,但没有通过其他测试用例,这让我觉得这里隐藏了一个逻辑问题。
这是我目前所拥有的:
public class Messaging {
//times in millis
double time_before;
double time_now;
double now;
double time_passed;
double allowance;
//constants
static double per = 50000; // 50 seconds
static double rate = 5; //5 messages
public Messaging(){
time_before = System.currentTimeMillis();
allowance = rate;
}
public void onEvent(){
time_now = System.currentTimeMillis();
time_passed = time_now - time_before;
time_before = time_now;
allowance += time_passed * (rate / per);
if (allowance > rate){
allowance = rate;
System.out.println("Reset Allowance");
}
if (allowance < 1.0){
System.out.println("Discard");
}else{
System.out.println("Forward message");
allowance -= 1.0;
}
}
但这不起作用!
public static void main(String[] args) {
Messaging orders = new Messaging();
for (int i = 0; i < 10; i++) {
orders.onEvent();
try {
Thread.sleep(5000);
} catch (Exception ex) {
}
}
}
运行上面的代码会得到:
Forward message. Time: 1469830426910
Forward message. Time: 1469830431912
Forward message. Time: 1469830436913
Forward message. Time: 1469830441920
Forward message. Time: 1469830446929
Forward message. Time: 1469830451937
Forward message. Time: 1469830456939
Forward message. Time: 1469830461952
Forward message. Time: 1469830466962
Discard. Time: 1469830471970
Total time passed: 50067
为什么只丢弃最后一条消息?不应该将津贴减少到足以在第 5 条消息后自动失败吗?
我希望获得有关此特定实施的帮助。实际实现将使用没有队列等的专有语言。
【问题讨论】:
-
我们无法提供任何信息,因为您的输出没有时间戳。我们没有办法知道发生了什么。一个建议:将过滤代码与时间戳解耦,这样无论调试如何,您都可以为其提供一组可重复的测试数据。这将让您逐步完成代码并弄清楚这一点。
-
@JimGarrison 我添加了时间戳输出。我正在测试不同的变体,所以现在只需使用 Thread.sleep 来模拟每 x 秒出现的消息。单步执行代码我可以告诉
allowance += time_passed * (rate / per);行是造成问题的原因,但是由于我在许多实现中都看到了相同的行,所以我想知道我是否在我的特定做错了什么或者这个算法没有为滑动窗口工作。 -
这不是他的意思——我目前正在写一个答案,希望能解释一下。
标签: java algorithm message-queue