2016-11-24 113 views
1

當我從學生名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"); 

    } 
} 

。所以在這裏

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的結果和你:

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; 
    } 

} 
+0

最簡單的方法是在'call()'中捕獲任何異常。你只需要弄清楚返回什麼來表明執行沒有完美的完成。其他選項是將'get()'調用用自己的try/catch塊封裝在for循環中。取決於你想在哪裏以及如何處理異常行爲。 – Fildor

+0

在應用程序的情況下,如果我們在調用方法中捕獲異常,我們將在錯誤情況下返回什麼。我的意思是將如何處理這種錯誤 – coder25

+1

這取決於您。取決於你的設計。你可以簡單地返回null或者一個空字符串或者一些定義好的「Poison」常量......很多可能性。但就你的情況而言,我想如下面的答案中所描述的那樣去做更爲可行。 – Fildor

回答

2

就可以在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(); 
} 

將是相當可以處理每項任務的特殊執行。

+0

理想情況下,它應該在呼叫方法內還是在周圍捕獲異常獲得 – coder25

+1

@ coder25這取決於您可以以正確的方式處理異常,以便您的應用程序保持良好狀態。 –

+0

那麼,這個具體問題並沒有真正的答案,因爲示例代碼看起來頗爲理想。在現實生活中,它取決於可以處理異常**的位置。如果來電者不需要知道特殊行爲,請在裏面進行。如果呼叫者需要採取一些措施保持一致,那麼你必須趕到外面。 – Fildor

0

這種模式應該是:主線程創建並調用從屬線程,它應該返回ok值或錯誤值(如果有任何錯誤)。然後主線程應該收集從屬結果並處理它們。

+1

你怎麼知道?這完全是一個設計決定。 – Fildor