java - Executor Service 和 Rate Limiter

标签 java multithreading executorservice

我有一个调用 3rd 方 API 的类。现在我正在实现一次只能向第 3 方 api 发送 10 个请求。

我想过使用具有固定线程池的执行程序服务,如下所示。

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 个工作线程,所以在任何时候都只能使用上述代码向 3rd 方 API 发出 10 个请求。但这并不意味着 Executor 服务会拒绝所有其他请求。相反,它会接受所有请求并将请求分配给工作线程,一旦它完成了它正在处理的任务的执行。

Is the above understanding correct?

最佳答案

是的,您的理解是正确的,如果您查看 Executors.newFixedThreadPool() 的实现,它会返回一个 ThreadPoolExecutor 实例,并带有 无界 BlockingQueue 实现:

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

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

相反,如果您使用自定义 ThreadPoolExecutor 和有界 BlockingQueue 实现,如 ArrayBlockingQueue(具有预定义容量)而不是 LinkedBlockingQueue 在这种情况下,如果所有线程都忙且队列已满,并且您尝试提交另一个任务,则该任务将是拒绝了。

在您的代码中,executorService.submit 将继续接受新任务(直到 Integer.MAX_VALUE 任务),但在给定的时刻只有 10 个线程会运行。

关于java - Executor Service 和 Rate Limiter,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55772945/

相关文章:

java - 如何在Java中对多个列表进行排序

java - 如何设计以避免在初始化字段时主线程异常上的数据库访问?

java - 逐行读取文件夹中的所有.txt 文件

java - 获取每个 executorservice 线程背后的查询

java - 从不同线程将值添加到全局集中并等待所有线程完成

java - 验证失败时阻止操作

java - selenium webdriver 如何使用对象标签?

java - java中的同步重新排序

java - ExecutorService 并发行为不稳定且不稳定

java - Executor框架和JMS等消息队列的区别