5

我有一个执行一些 IO 的方法,我想限制对该方法的调用(每秒),以避免后端获得它无法处理的并发请求突发。

如果要求没有“每秒”,我可以只使用一个堆栈(基本上只是一个计数器),并offer()在开始请求时以及poll()完成时使用。有了“每秒”的要求,我不知何故需要清理堆栈上比给定时间流逝更旧的插槽。

我该如何正确地做到这一点?显然,该结构应该是线程安全的。

感谢您的时间!

4

3 回答 3

4

看看这个问题。答案同样适用于这个问题,即使这个问题的措辞完全不同。

我承认,我觉得它有点神秘,但效果很好。

于 2011-05-18T16:26:08.473 回答
3

您可以使用队列,但需要进行一些修改。每当您想添加到队列中(该方法被调用)时,您都会检查其中有多少元素以及添加它们的时间。可以删除超过一秒前插入的所有元素。将剩余元素的数量与每秒的速率进行比较,您可以决定是否拒绝方法执行。如果您打算使用方法块而不是拒绝,它可能会变得有点复杂。

可能有许多可能的实现,您必须检查它们是否适用于您的问题。您还可以查看令牌桶的实现,这是您问题的一般概念。

于 2011-05-18T09:36:22.820 回答
0

听起来您需要将 IO 工作与请求线程分离,并将其卸载到具有给定大小的线程池中。这样您就可以显式控制同时执行 IO 的线程数。

ExecutorService pool = Executors.newFixedThreadPool(10);

public void myMethod() {

  pool.submit(new Runnable() {
    public void run() {
      //Do IO work here
    }
  });

}

在这个例子中,做 IO 工作的线程永远不会超过 10 个。它不限制每秒的请求数,但控制并发可能是一种更好的节流方式。

于 2011-05-18T09:57:55.483 回答