[英]How to stop Callable tasks in Executor service if exception occur
我正在嘗試實現一個示例應用程序來測試 Callable 和 ExecutorService 接口。
在我的應用程序中,我有:
@Bean("fixedThreadPool")
public ExecutorService fixedThreadPool() {
return Executors.newFixedThreadPool(5);
}
然后:
public void removeUserIds(Set<String> userIds) {
UriComponentsBuilder builder = UriComponentsBuilder.fromUriString("http://localhost:8080/remove");
final List<Callable<String>> callables = new ArrayList<>();
userIds.forEach(userId -> {
final Callable<String> task = () -> callServiceToRemove(builder,userId); //Call to remote service using RestTemplate
callables.add(task);
});
try {
final List<Future<String>> futureList =
executor.invokeAll(callables);
futureList.forEach(future -> {
try {
log.info(future.get());
} catch (final Exception e) {
log.error("Error : "+ e.getMessage());
}
});
} catch (final Exception e) {
log.error("Error Error Error : "+ e.getMessage());
} finally {
executor.shutdown();
}
}
當我使用 100 個用戶 ID 調用 removeUserIds() 方法時,它在愉快的流程中工作正常,但如果服務不可用或關閉,第 100 次將打印錯誤。 如果服務不可用或關閉,我將無法停止/終止線程,因此服務不會發生進一步的調用。 任何人都可以幫助解決這個問題,如果服務關閉,我如何停止線程執行,或者在這里提出可行的解決方案?
在 try catch 塊中移動 callServiceToRemove 調用。
在 catch 塊中,您可以使用 executor.shutdownNow();
shutdownNow()嘗試停止所有正在執行的任務,停止等待任務的處理,並返回等待執行的任務列表。 此方法不會等待主動執行的任務終止並嘗試強制停止它們。 除了盡力嘗試停止處理正在執行的任務之外,沒有任何保證。 此實現通過 Thread.interrupt() 取消任務,因此任何未能響應中斷的任務可能永遠不會終止。
這與其說是編碼問題,不如說是設計問題。 可能有幾種方法。 你可以以這個為例:
在實際觸發遠程服務調用之前,查找全局布爾標志,例如Globals.serviceUnavailable
。 這個全局標志可以由遇到遠程錯誤的第一個服務設置。 以下是對代碼的更改。
final Callable<String> task = () -> {
try{
if( !Globals.serviceUnavailable ) callServiceToRemove(builder,userId);
}
catch( ServiceUnavailableException e ){ //Or whatever your exception is
Globals.serviceUnavailable = true; //Notify the remaining tasks that the service is unavailable.
}
}
當然,您必須查看是否必須同步更新Globals.serviceUnavailable
的值。 (如果您可以部分成功刪除一批用戶 ID,則可能沒有必要。)
此外,只有當您的線程池遠小於提交的任務數量時,這才有效,我在這里看到的就是這種情況。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.