编写一个不能过于频繁调用的方法的正确方法是什么?

时间:2014-08-31 17:39:04

标签: java

假设我有一个类,我不希望每五秒钟调用一次以上的方法(例如,它会查询将过于频繁发送查询的应用程序列入黑名单的Web服务器)。实现这个的最佳方法是什么?

我提出的解决方案是让方法在每次通过调用System.currentTimeMillis()运行时在静态成员变量中存储时间戳,并在执行时间敏感代码之前检查此时间戳。但是我很紧张,因为我没有预见到的突发事件,所以我想看看是否有一种标准的方法可以解决这个问题。

3 个答案:

答案 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; 
}