[英]How to work correctly with ThreadPoolExecutor in Spring Boot Application
我有一個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 。 例如,我需要在ArrayList
寫入執行的網址:
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
必須將其關閉。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.