Java 编写能够';不要打得太频繁?
假设我有一个类,其中包含一个方法,我不希望每五秒钟被调用一次以上(例如,它查询一个web服务器,该服务器将频繁发送查询的应用程序列入黑名单)。实现这一点的最佳方式是什么Java 编写能够';不要打得太频繁?,java,Java,假设我有一个类,其中包含一个方法,我不希望每五秒钟被调用一次以上(例如,它查询一个web服务器,该服务器将频繁发送查询的应用程序列入黑名单)。实现这一点的最佳方式是什么 我提出的解决方案是让该方法每次通过调用System.currentTimeMillis()在静态成员变量中存储一个时间戳,并在执行时间敏感代码之前检查这个时间戳。但是我很紧张,我没有预见到一些突发事件,所以我想看看是否有一个标准的方法来处理这个问题 因为您提到它是一个web应用程序,所以您的方法将在所有调用(即来自所有活动会话)
我提出的解决方案是让该方法每次通过调用
System.currentTimeMillis()
在静态成员变量中存储一个时间戳,并在执行时间敏感代码之前检查这个时间戳。但是我很紧张,我没有预见到一些突发事件,所以我想看看是否有一个标准的方法来处理这个问题 因为您提到它是一个web应用程序,所以您的方法将在所有调用(即来自所有活动会话)之间共享时间戳变量。这似乎不是你想要实现的
一种标准的“web应用程序”方法是在会话上放置一个计时器对象,并编写一个过滤器来管理计时器。我没有听说标准方法,但我解决了这个问题,因为我想太频繁地获取ntp时间,ntp服务器阻止了我的请求。因此,以下代码为我实现了这一点:
public static long getTime(){
//检查是否应进行更新
如果(System.currentTimeMillis()-updateTime>CLOCK\u SYNC\u INTERVAL\u MS){
//在新线程中执行更新
新线程(新Runnable(){
@凌驾
public void run(){
updatelock();
}
}).start();
}
返回System.currentTimeMillis()-updateTime+nts;
}
用番石榴。简单的例子:
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!");
}
}
}
没有标准的方法。所以你认为存储最后一次调用的时间戳是可以的。我会让这个方法可以在另一个线程上执行,而不会停止当前应用程序的运行。如果您希望该方法不能在应用程序级别如此频繁地执行,则将其设置为
静态
,并使用静态
字段来执行该方法和测量时间,并将其同步。@luigimendoza该方法根本不必是静态的;事实上,可以定义一组方法来共享相同的超时策略。所有这些方法(可能来自几个不同类型的实例)都会引用相同的静态计时数据。请同步该方法,并通过线程占用该方法5秒。没有标准方法。您的策略将很好地发挥作用。领先的Java应用程序服务器不喜欢用户生成线程。他们希望您从容器的托管池中获取线程。