【问题标题】:Thread pool in each api request vs single application pool reuse每个 api 请求中的线程池与单个应用程序池重用
【发布时间】:2022-01-01 21:50:22
【问题描述】:

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

  1. 是每个请求都有 ExecutorService 线程池,还是为应用程序创建一个池并重用它?
  2. 如何确定 Executors 服务的池大小。
@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;
            }

【问题讨论】:

    标签: java multithreading spring-boot threadpool


    【解决方案1】:

    线程是通过程序代码执行的独立路径。创建线程是一项昂贵的任务。需要做很多工作,比如分配内存、初始化线程堆栈。

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

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

    【讨论】:

    • 如果你已经创建了一次池,如何关闭池线程池?
    • 您可以在 ContextClosedEvent 上使用 DisposableBean 或 ApplicationListener 接口来关闭线程池。
    【解决方案2】:

    你可以使用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 this for maxPoolSize, corePoolSize, queueSize.

    【讨论】:

      猜你喜欢
      • 2012-09-03
      • 2016-10-18
      • 2019-02-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-08
      相关资源
      最近更新 更多