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