如果发生异常,如何在Executor服务中停止可调用任务 [英] How to stop Callable tasks in Executor service if exception occur

查看:74
本文介绍了如果发生异常,如何在Executor服务中停止可调用任务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试实现一个示例应用程序来测试Callable和ExecutorService接口.

I'm trying to implement a sample application to test Callable and ExecutorService interfaces.

在我的应用中,我有:

@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个userIds调用removeUserIds()方法时,它在正常运行中运行良好,但是如果服务不可用或服务中断,则错误将第100次显示.如果服务不可用或关闭,我将无法停止/终止线程,因此服务不会发生进一步的调用. 有谁可以帮助解决此问题,如果服务中断,我如何停止线程执行,还是在这里建议可行的解决方案?

When I am calling removeUserIds() method with 100 userIds, It is working fine in happy flow, but if service is unavailable or down, error is getting printed 100th time. I am not able to stop/terminate thread if service is unavailable or down, so further call will not happen to service. Could any one help here to fix this issue, how I can stop thread execution if service is down, or suggest feasible solution here?

推荐答案

与编码问题相比,这更多的是设计问题.可能有几种方法.您可以以这个为例:

This is a more a design problem than a coding issue. There may be several approaches. You may take this one for example:

在实际触发远程服务调用之前,先查找全局布尔标志,例如Globals.serviceUnavailable. 可由遇到远程错误的第一个服务设置此全局标志.这是对代码的更改.

Look for a global boolean flag, say Globals.serviceUnavailable, before actually firing the remote service call. This global flag can be set by the first service(s) that encounter the remote error. Here are the changes to the code.

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,则可能没有必要.)

Of course, you will have to see if updating the value of Globals.serviceUnavailable has to be synchronized. (It may not be necessary if you are OK for a partial success of removal of the batch of user Ids.)

此外,这仅在您的线程池比已提交任务的数量小得多的情况下才有效,我在这里就是这种情况.

Also, this will work only if your thread pool is much smaller than the number of submitted tasks, which I see is the case here.

这篇关于如果发生异常,如何在Executor服务中停止可调用任务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆