4

我正在寻找一个好的解决方案或者可能是一个 API 来解决以下问题:

  • 我的应用程序循环执行一项任务,例如它发送电子邮件等。我需要将平均消息速率限制为例如每秒 100 条消息或每最后一分钟 1000 条消息......

不,我正在寻找完全执行此任务的算法或 API。

4

4 回答 4

4

您可以使用ScheduledExecutorService在给定的时间段内安排任务。

例如,要每秒安排 100 个任务,您可以说:

ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(nThreads);
scheduler.scheduleAtFixedRate(mailSender, 0, 10, TimeUnit.MILLISECONDS);

显然,您需要跟踪执行了多少任务并在作业完成后关闭调度程序。

于 2011-09-08T14:48:52.237 回答
4

令牌桶算法非常易于实现和使用,但功能非常强大。您可以在运行时控制吞吐量并将一些请求排队以处理窥视。

于 2011-09-08T14:49:59.587 回答
3

我能想到的最简单的方法是延迟发送每封电子邮件的时间,具体取决于等待的数量。

final ScheduledThreadPoolExecutor service = new ScheduledThreadPoolExecutor(1);
int ratePerSecond = ...

public static void execute(Runnable run) {
   int delay = 1000 * service.getQueue().size() / ratePerSecond;
   service.schedule(run, delay, TimeUnit.MILLISECONDS);
}

这将确保任务仅在速率允许的情况下尽可能靠近地执行。

于 2011-09-08T15:07:48.397 回答
3

Guava 有一个RateLimiter类可以做到这一点。

于 2013-06-06T12:07:33.863 回答