执行器服务和速率限制器

时间:2019-04-20 11:13:33

标签: java multithreading executorservice

我有一个调用第三方API的类。现在,我正在实施,每次仅需要将10个请求发送到第三方api的实现。

我考虑过将执行程序服务与固定线程池一起使用,如下所示。

public class SimpleRateLimiter {

    private ExecutorService executorService = Executors.newFixedThreadPool(10);
    private static SimpleRateLimiter srl = new SimpleRateLimiter();

    private SimpleRateLimiter() {}

    public static SimpleRateLimiter getInstance() {
        return srl;
    }

    public void doSomething() {
        executorService.submit(new Runnable() {         
            @Override
            public void run() {

                // call to 3rd party api
            }
        });
    }

    public void terminate() throws Exception {
        executorService.shutdown();
    }

}

我的理解是,由于我在池中只有10个工作线程,因此在任何时候都可以使用上述代码向第三方API发出10个请求。但这并不意味着Executor服务将拒绝所有其他请求。相反,它将在完成正在执行的任务后接受所有请求并将请求分配给工作线程。

  

以上理解正确吗?

2 个答案:

答案 0 :(得分:2)

是的,您的理解是正确的,如果您查看Executors.newFixedThreadPool()的实现,它将返回带有 unbounded {{ 1}}实现:

ThreadPoolExecutor

BlockingQueue是一个可选的有界 public static ExecutorService newFixedThreadPool(int nThreads) { return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()); } 实现,如果您不提供任何内容,队列的最大大小为LinkedBlockingQueue,则可以忽略其构造函数的Capacity参数:

BlockingQueue

因此,关于您的问题所有任务都将提交到线程池,并且一次只有10个线程将运行并进行API调用,其余的将排队。

相比之下,如果您使用自定义Integer.MAX_VALUE和有界public LinkedBlockingQueue() { this(Integer.MAX_VALUE); } 的实现,例如ThreadPoolExecutor(具有预定义的容量),而不是BlockingQueue线程忙,队列已满,您尝试提交另一个任务,该任务将被拒绝

在您的代码中,ArrayBlockingQueue将继续接受新任务(直到LinkedBlockingQueue任务),但在给定的时间点将仅运行10个线程。

答案 1 :(得分:0)