我有一个执行一些 IO 的方法,我想限制对该方法的调用(每秒),以避免后端获得它无法处理的并发请求突发。
如果要求没有“每秒”,我可以只使用一个堆栈(基本上只是一个计数器),并offer()
在开始请求时以及poll()
完成时使用。有了“每秒”的要求,我不知何故需要清理堆栈上比给定时间流逝更旧的插槽。
我该如何正确地做到这一点?显然,该结构应该是线程安全的。
感谢您的时间!
我有一个执行一些 IO 的方法,我想限制对该方法的调用(每秒),以避免后端获得它无法处理的并发请求突发。
如果要求没有“每秒”,我可以只使用一个堆栈(基本上只是一个计数器),并offer()
在开始请求时以及poll()
完成时使用。有了“每秒”的要求,我不知何故需要清理堆栈上比给定时间流逝更旧的插槽。
我该如何正确地做到这一点?显然,该结构应该是线程安全的。
感谢您的时间!
看看这个问题。答案同样适用于这个问题,即使这个问题的措辞完全不同。
我承认,我觉得它有点神秘,但效果很好。
您可以使用队列,但需要进行一些修改。每当您想添加到队列中(该方法被调用)时,您都会检查其中有多少元素以及添加它们的时间。可以删除超过一秒前插入的所有元素。将剩余元素的数量与每秒的速率进行比较,您可以决定是否拒绝方法执行。如果您打算使用方法块而不是拒绝,它可能会变得有点复杂。
可能有许多可能的实现,您必须检查它们是否适用于您的问题。您还可以查看令牌桶的实现,这是您问题的一般概念。
听起来您需要将 IO 工作与请求线程分离,并将其卸载到具有给定大小的线程池中。这样您就可以显式控制同时执行 IO 的线程数。
ExecutorService pool = Executors.newFixedThreadPool(10);
public void myMethod() {
pool.submit(new Runnable() {
public void run() {
//Do IO work here
}
});
}
在这个例子中,做 IO 工作的线程永远不会超过 10 个。它不限制每秒的请求数,但控制并发可能是一种更好的节流方式。