我有多个线程消耗一些数据并调用一个第三方服务(serviceA
)。我每10秒只能向serviceA
发送一个请求。每个线程必须等待,直到收到来自serviceA
的结果,然后继续执行其他线程特定的工作。
我想为serviceA
实现某种代理,该代理将接收对serviceA
的所有调用,收集它们,每10秒执行一次调用,并返回此调用的结果。每个线程应等待代理返回结果。它应该看起来像这样
public class ServiceAProxy implements ServiceA {
private ServiceA serviceA;
private ??? callsHolder;
public ServiceAProxy(ServiceA serviceA) {
this.serviceA = serviceA;
}
public Result call(String parameter) {
return callsHolder.submitAndWaitResult(() -> serviceA.call(parameter));
}
@Scheduled(fixedDelay = 10000)
public void executeOldestCall() {
callsHolder.executeOldestTask();
}
}
可能callHolder
可以使用2个SynchronousQueue
来实现,但是有没有更清洁的解决方案来做到这一点而又无需重新发明轮子?
答案 0 :(得分:1)
如果线程数很小,并且阻塞调用线程直到可以发送请求就没什么大不了了,Guava RateLimiter可能就足够了。因此,您的服务代理将如下所示:
public class ServiceAProxy implements ServiceA {
private final ServiceA serviceA;
private final RateLimiter throttle;
public ServiceAProxy(ServiceA serviceA, double callsPerSecond) {
this.serviceA = serviceA;
throttle = RateLimiter.create(callsPerSecond);
}
public Result call(String parameter) {
// every thread may potentially block here until throttle allows it to proceed
throttle.acquire();
return serviceA.call(parameter);
}
}