我想对从客户端收到的每个请求并行运行一些任务。我使用spring-boot来运行服务器,并在HTTPapi调用上调用getItems方法。我正在使用Executors.newCachedThreadPool((生成多个线程。我需要一些关于以下实现的输入
- 每个请求都有ExecutorService线程池,还是为应用程序创建一个池并重用它
- 如何决定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;
}
线程是通过程序代码执行的独立路径。创建线程是一项昂贵的任务。还有很多工作需要做,比如分配内存、初始化线程堆栈。
-
创建一次线程池是很好的针对应用程序,而不是针对每个请求。它减少了开销处理请求的延迟。在Spring引导中,您可以定义豆子。
@Bean("cachedThreadPool") public ExecutorService cachedThreadPool() { return Executors.newCachedThreadPool(); }
-
考虑使用最大池大小为50。有线程池是没有意义的在这种情况下为100。所以最好决定最大值基于您所使用的用例的线程数。
您可以使用spring ThreadPoolTaskExecutor。在这里,您可以配置池大小、最大池大小、队列大小等。
@Bean
ThreadPoolTaskExecutor taskExecutor() {
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
taskExecutor.setCorePoolSize(500);
taskExecutor.setMaxPoolSize(1000);
taskExecutor.setQueueCapacity(200);
taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
return taskExecutor;
}
请检查maxPoolSize、corePoolSize和queueSize。