每个 api 请求中的线程池与单个应用程序池重用

Thread pool in each api request vs single application pool reuse

我想 运行 对从客户端收到的每个请求并行处理几个任务。我正在使用 spring 引导至 运行 服务器并在 HTTP api 上调用它调用 getItems 方法。我正在使用 Executors.newCachedThreadPool() 生成多个线程。我需要一些关于以下实现的输入

  1. 每个请求都有 ExecutorService 线程池好还是为应用程序创建一次池并重用好?
  2. 如何确定执行程序服务的池大小。
@Override
            public List<Item> getItems(List<String> id) {
                List<Item> items = new ArrayList<>();
                ExecutorService execSvc = Executors.newCachedThreadPool();
                List<Callable<Item> > inventories = id.stream()
                        .map((itemId)-> (Callable<Item>) () -> {
                            List<InventoryNode> inventoryNodes =  getInventory(itemId);
                            return getItem(inventoryNodes);
                        }).collect(Collectors.toList());
                try {
                    List<Future<Item>> results = execSvc.invokeAll(inventories);
                    for(Future<Item> inventory :results){
                        if(inventory.isDone()){
                            items.add(inventory.get());
                        }
                    }
                } catch (InterruptedException | ExecutionException e) {
                    e.printStackTrace();
                }finally {
                    execSvc.shutdown();
                }
                return items;
            }

线程是程序代码的独立执行路径。创建线程是一项昂贵的任务。分配内存,初始化线程栈等很多工作需要完成。

  1. 创建一次线程池就好了 针对应用程序而不是针对每个请求。它减少了开销和 处理请求的延迟。在 Spring boot 你可以定义一个 豆子。

     @Bean("cachedThreadPool")
     public ExecutorService cachedThreadPool() {
        return Executors.newCachedThreadPool();
     }
    
  2. 考虑一个数据库连接 最大池大小为 50。拥有线程池没有意义 在这种情况下为 100。所以最好决定最大 基于您所处用例的线程数。

您可以使用spring ThreadPoolTask​​Executor。在这里您可以配置池大小、最大池大小、队列大小等。

@Bean
ThreadPoolTaskExecutor taskExecutor() {
    ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
    taskExecutor.setCorePoolSize(500);
    taskExecutor.setMaxPoolSize(1000);
    taskExecutor.setQueueCapacity(200);
    taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
    return taskExecutor;
}

Check 这就是 maxPoolSize、corePoolSize、queueSize。