每个 api 请求中的线程池与单个应用程序池重用
Thread pool in each api request vs single application pool reuse
我想 运行 对从客户端收到的每个请求并行处理几个任务。我正在使用 spring 引导至 运行 服务器并在 HTTP api 上调用它调用 getItems 方法。我正在使用 Executors.newCachedThreadPool() 生成多个线程。我需要一些关于以下实现的输入
- 每个请求都有 ExecutorService 线程池好还是为应用程序创建一次池并重用好?
- 如何确定执行程序服务的池大小。
@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 boot 你可以定义一个
豆子。
@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;
}
Check 这就是 maxPoolSize、corePoolSize、queueSize。
我想 运行 对从客户端收到的每个请求并行处理几个任务。我正在使用 spring 引导至 运行 服务器并在 HTTP api 上调用它调用 getItems 方法。我正在使用 Executors.newCachedThreadPool() 生成多个线程。我需要一些关于以下实现的输入
- 每个请求都有 ExecutorService 线程池好还是为应用程序创建一次池并重用好?
- 如何确定执行程序服务的池大小。
@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 boot 你可以定义一个 豆子。
@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;
}
Check 这就是 maxPoolSize、corePoolSize、queueSize。