【问题标题】:exception handling in executor service执行器服务中的异常处理
【发布时间】:2016-11-24 07:53:26
【问题描述】:

当我从学生名 archana 中抛出异常时。 据我了解 InvokeAll 等待所有任务完成,然后返回未来列表

我得到的输出是

 pool-1-thread-1 Helloprerna   
 pool-1-thread-2 Helloabc   
 HELLO SOMEERROR   
 Execution Completed

我希望显示其他任务的输出不抛出异常。任何建议

public class Executor {

    public static void main(String args[]) throws InterruptedException{

        ExecutorService  executor=Executors.newFixedThreadPool(5);

        ArrayList<Student> list = new ArrayList<Student>();
        list.add(new Student("prerna"));
        list.add(new Student("abc"));
        list.add(new Student("archana"));
        list.add(new Student("def"));
        list.add(new Student("xyz"));
        list.add(new Student("ritu"));
        list.add(new Student("babita"));

        try {
            List<Future<String>> resultList=executor.invokeAll(list);
            for(Future<String> f:resultList){
                //if(f.isDone()){
                    System.out.println(f.get());
                //}
            }
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }catch (ExecutionException e) {
            // TODO Auto-generated catch block
            System.out.println("HELLO SOME ERROR");
            //e.printStackTrace();
        }

        executor.shutdown();
        executor.awaitTermination(10, TimeUnit.SECONDS);
          System.out.println("Execution Completed");

    }
}

.

public class Student implements Callable<String>{
    String name;
    public Student(String name) {
        super();
        this.name = name;
    }

    @Override
    public String call() throws Exception {
        // TODO Auto-generated method stub
        if(name=="archana"){
            throw new Exception();
        }
        return display(name);
    }

    private String display(String name2) {
        try {
        //  System.out.println(Thread.currentThread().getName());
            name2=Thread.currentThread().getName()+" Hello"+ name;
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return name2;
    }

}

【问题讨论】:

  • 最简单的方法是在call() 中捕获任何异常。你只需要弄清楚要返回什么来表明执行没有优雅地完成。其他选择是将 get() 调用与它自己的 try/catch 块一起包含在 for 循环中。取决于您希望在何处以及如何处理异常行为。
  • 在应用的情况下,如果我们在调用方法中捕获异常,我们将在错误的情况下返回什么。我的意思是如何完成这样的错误处理
  • 这取决于你。取决于你的设计。您可以简单地返回 null 或一个空字符串或一些定义的“毒药”常量......很多可能性。但在你的情况下,我想按照我下面的回答中描述的那样去做会更可行。

标签: java multithreading future executorservice


【解决方案1】:

你可以在 try/catch 中移动:

原文:

try {
    List<Future<String>> resultList=executor.invokeAll(list);
    for(Future<String> f:resultList){
    //  if(f.isDone()){

                System.out.println(f.get());

        //}
    }
} catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}catch (ExecutionException e) {
    // TODO Auto-generated catch block
    System.out.println("HELLO SOME ERROR");
//  e.printStackTrace();
}

宁可:

try {
    List<Future<String>> resultList=executor.invokeAll(list);
    for(Future<String> f:resultList){
        try{
            System.out.println(f.get());
        }catch (ExecutionException e) {
            System.out.println("HELLO SOME ERROR: " + e.getMessage());
        }
} catch (InterruptedException e) {
    e.printStackTrace();
}

所以在这里你会得到所有 OK 的结果,你可以处理每个任务的异常执行。

【讨论】:

  • 理想情况下应该在哪里缓存调用方法中的异常或捕获get
  • @coder25 这取决于您可以在哪里以适当的方式处理异常,以便您的应用程序保持良好状态。
  • 嗯,这个具体问题并没有真正的答案,因为示例代码看起来相当学术。在现实生活场景中,这将取决于异常可以处理的位置。如果调用者不需要了解异常行为,请在内部进行。如果调用者需要采取一些措施来保持一致的状态,那么你必须赶在外面。
  • 任何现实生活中的例子都可以在里面或外面捕捉。我正在准备面试。
  • @coder25 如果要求所有线程都成功退出以获得有效结果(如计算),则在for 循环之外捕获异常。如果你,例如想要重新提交失败的任务(例如 web 服务调用),您可以在循环中捕获异常,如果您只想记录失败并继续前进(一些 fire and forget 场景),您可以这样做它在call() 方法中(或在for 中)...
【解决方案2】:

这个模式应该是:主线程创建和调用从线程,它应该返回 ok 值或错误值(如果有任何错误)。然后主线程应该从slave收集结果并处理它们。

【讨论】:

  • 你怎么知道的?这完全是一个设计决定。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-17
  • 1970-01-01
  • 2011-08-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多