java - 如何在 Spring Boot 应用程序中正确使用 ThreadPoolExecutor
问题描述
我有一个Spring Boot Application
.
我的应用程序使用restTemplate
.
我需要向一百个不同的应用程序(在不同的服务器上)发送请求。我用:
publi class Service {
private RestClient restClient;
private List<String> urls;
private ThreadPoolExecutor executor;
public Service(RestClient restClient, List<String> urls, ThreadPoolExecutor executor){
this.restClient = restClient;
this.urls = urls;
this.executor = executor;
}
public void sendPost(Entity entity){
for (String url: urls){
executor.execute(() -> restClient.create(url, entity);
}
}
}
我正在尝试使用ThreadPoolExecutor(fixedSizeThreadPool)
,但我有一些问题。
1 .我读到这threadPoolExecutor
是线程安全的。这是否意味着我可以execute()
从不同的线程同时调用并且它会正常工作?
2 . 如果没有空闲线程threadPoolExecutor
它会减慢应用程序的速度,我应该选择合理的池大小,对吗?
3 . 例如,我需要在以下位置编写执行的 url ArrayList
:
public void sendPost(Entity entity){
List<String> executedUrls = new ArrayList<>();
for (String url: urls){
executor.execute(() -> restClient.create(url, entity, executedUrls);
}
}
RestClient
发送请求,如果执行成功,会被添加到ArrayList
.
如果我ArrayList
在来自threadPool
.
它会按我的预期工作还是我会丢失更新之类的东西?
解决方案
您可以做的是使用ExecutorService
.
例如,创建一个新ExecutorService
的(缓存的ThreadPoolExecutor
可能更好)
private final ExecutorService executorService = Executors.newCachedThreadPool();
创建自定义Runnable
实现
static class RestRunnable implements Runnable {
private final String url;
private final RestTemplate restTemplate;
private final Collection<? super String> executedUrls;
RestRunnable(
final String url,
final RestTemplate restTemplate,
final Collection<? super String> executedUrls) {
this.url = url;
this.restTemplate = restTemplate;
this.executedUrls = executedUrls;
}
@Override
public void run() {
final ResponseEntity<?> response = restTemplate.exchange(...);
if (response.getStatusCode() == HttpStatus.OK) {
executedUrls.add(url);
}
}
}
并为每个URL
人提交一个新任务到ExecutorService
final Collection<String> urls = new ArrayList<>();
final Collection<String> executedUrls = new CopyOnWriteArrayList<>();
...
for (final String url : urls) {
// The RestTemplate instance is retrieved via Spring Bean, or created manually
executorService.submit(new RestRunnable(url, restTemplate, executedUrls));
}
RestRunnable
如果成功调用,则将其URL
插入线程executedUrls
安全中。CopyOnWriteArrayList
请记住,不再需要时ExecutorService
必须关闭。
推荐阅读
- javascript - Promise 链无法解析;什么是正确的修复方法?
- python - 我是否负责实现导致 check_unused_args(used_args, args, kwargs) 引发异常的代码?
- c# - Docker 仅针对 http 端口返回响应
- excel-formula - 基于 COUNTIF 函数的彩色 Excel 单元格
- raspberry-pi - aplay 声音测试和 espeak 设置
- azure - 无法在 Azure IP 保留向导中保留静态 IP
- oracle - 在 RMAN 备份期间,关闭即时数据库并面临错误 ORA-12514: TNS:listener?
- amazon-web-services - AWS EKS 集群、DockerHub 和 Traefik,无法从 Internet 访问
- python - 为什么numpy数组nan的max和min是?
- typescript - 我应该如何使用 TypeScript 编译器 API 获得 Common JS 导出?