假设我有一个类,我不希望每五秒钟调用一次以上的方法(例如,它会查询将过于频繁发送查询的应用程序列入黑名单的Web服务器)。实现这个的最佳方法是什么?
我提出的解决方案是让方法在每次通过调用System.currentTimeMillis()
运行时在静态成员变量中存储时间戳,并在执行时间敏感代码之前检查此时间戳。但是我很紧张,因为我没有预见到的突发事件,所以我想看看是否有一种标准的方法可以解决这个问题。
答案 0 :(得分:5)
使用番石榴RateLimiter。简单的例子:
public static void main(String[] args) {
callForeverWithRateLimited();
}
public static void callForeverWithRateLimited() {
RateLimiter rateLimiter = RateLimiter.create(1); // 1 QPS (query per second)
while (true) {
if (rateLimiter.tryAcquire()) {
System.out.println("my rate was limited!");
}
}
}
答案 1 :(得分:0)
由于您已经提到它是一个Web应用程序,因此您的方法将在所有调用之间共享时间戳变量,即来自所有活动会话。它似乎不是你想要实现的目标。
标准"网络应用程序"方法是在会话上放置一个计时器对象,并编写一个管理计时器的过滤器。
答案 2 :(得分:0)
我没有听说过标准方式,但是我解决了这个问题,因为我想太频繁地获取ntp时间并且NTP服务器阻止了我的请求。所以下面的代码为我做了:
public static long getTime() {
// check whether a update should be done
if (System.currentTimeMillis() - updateTime > CLOCK_SYNC_INTERVAL_MS) {
// perform the update in a new thread
new Thread(new Runnable() {
@Override
public void run() {
updateClock();
}
}).start();
}
return System.currentTimeMillis() - updateTime + nts;
}