【发布时间】:2019-10-10 19:56:51
【问题描述】:
我正在使用的服务在 1 秒内发出 5 个请求后开始阻止请求。
在 Spring 中使用 Java 我正在寻找一种方法来对线程进行排队,这样一秒钟内最多 5 个线程可以访问临界区,并且一旦有带宽让它们继续,任何其他线程都会排队并释放.
目前我已经尝试使用锁进行此操作,但它会导致线程总是等待 1/5 秒,即使我们不会在不休眠的情况下达到每秒的最大调用次数。
Lock l = new ReentrantLock();
try {
l.lock();
//critical section
} finally {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
l.unlock();
}
有了这个实现,我永远不会超过每秒 5 次,但在一切准备好返回给用户之后,我也会导致响应延迟 200 毫秒。
我需要一个仅在需要延迟时才延迟线程的解决方案。在这种情况下,一秒钟内的第 6 个以上呼叫应该延迟,但前 5 个呼叫不需要延迟。同样,呼叫 6-11 可以同时进行。
【问题讨论】:
-
试试 Guava 的 RateLimiter。
-
为什么要限制每秒而不是一次只允许 5 个?
-
@daniu 当一个人完成另一个需要被允许进入。如果他们完成得非常快,超过 5 个可以在一秒钟内执行。上面的关键代码部分使用了第 3 方 api,每秒 5 次调用后将拒绝其他调用。
-
一旦你决定做什么,你需要释放锁。做实际工作时,你不能拿着锁。
标签: java multithreading concurrency critical-section