如果发生异常,如何在执行器服务中停止可调用任务



>我正在尝试实现一个示例应用程序来测试可调用和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 次打印。如果服务不可用或关闭,我无法停止/终止线程,因此服务不会发生进一步的调用。 任何人都可以在这里帮助解决此问题,如果服务关闭,我如何停止线程执行,或者在这里提出可行的解决方案?

这与其说是编码问题,不如说是一个设计问题。可能有几种方法。你可以以这个为例:

使用全局标志

在实际触发远程服务调用之前,查找全局布尔标志,例如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,则可能没有必要。

此外,仅当您的线程池远小于提交的任务数量时,这才有效,我在这里看到就是这种情况。

将调用服务删除调用移动到尝试捕获块内。

在 catch 块中,您可以使用 executor.shutdownNow((;

shutdownNow((尝试停止所有正在执行的任务,停止处理等待的任务,并返回等待执行的任务的列表。 此方法不会等待主动执行的任务终止,而是尝试强制停止它们。除了尽力尝试停止处理主动执行的任务之外,没有任何保证。此实现通过 Thread.interrupt(( 取消任务,因此任何无法响应中断的任务都可能永远不会终止。

相关内容

  • 没有找到相关文章

最新更新