gpt4 book ai didi

java - 如何在 Spring Boot 应用程序中正确使用 ThreadPoolExecutor

转载 作者:行者123 更新时间:2023-12-02 10:07:11 29 4
gpt4 key购买 nike

我有一个 Spring Boot 应用程序

我的应用程序使用 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。例如,我需要在ArrayList中写入执行的url:

public void sendPost(Entity entity){
List<String> executedUrls = new ArrayList<>();
for (String url: urls){
executor.execute(() -> restClient.create(url, entity, executedUrls);
}
}

RestClient发送请求,如果执行成功,就会添加到ArrayList中。

如果我在 threadPool 的任何线程中出现异常,我希望 ArrayList 将包含成功执行的 url 列表。
它会按我的预期工作吗?或者我可能会遇到丢失更新之类的情况?

最佳答案

您可以使用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必须在不再需要时关闭。

关于java - 如何在 Spring Boot 应用程序中正确使用 ThreadPoolExecutor,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55269656/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com