2016-08-04 34 views
0

In Java möchte ich mehrere Threads ausführen und die Antwort von allen von ihnen erhalten.Bei der Verwendung der ExecutorService.invokeAll gibt es eine Möglichkeit, alle Antworten zu erhalten, auch wenn eine Ausnahme aufgetreten ist

Das Problem, das ich habe, ist, wenn einer der threads löst eine Ausnahme, wenn ich die Zeichenfolge temp = r.get() fällt in den Fang und gibt mir nicht die Antwort von den verbleibenden Threads.

Gibt es eine Möglichkeit, alle Antworten zu verarbeiten, unabhängig davon, ob der einzelne Thread eine Ausnahme ausgelöst hat?

Mein Testcode ist

ExecutorService es = Executors.newFixedThreadPool(2); 
    List<CallTest> callList = new ArrayList<>(); 

    callList.add(new CallTest(1)); 
    callList.add(new CallTest(2)); 
    callList.add(new CallTest(3)); 
    callList.add(new CallTest(4)); 


    try { 
     List<Future<String>> returns = es.invokeAll(callList); 
     for (Future<String> r : returns) { 
      String temp = r.get(); 
      System.out.println("returned " + temp); 

     } 
    } catch (InterruptedException e) { 
     System.out.println("Interrupted Exception catch"); 
     e.printStackTrace(); 
    } catch (ExecutionException e) { 
     System.out.println("Execution Exception catch"); 
     e.printStackTrace(); 

    } 
+3

Setzen Sie den Try-Catch um die einzelnen 'r.get()' statt der gesamten Schleife? – RealSkeptic

Antwort

0

fangen Ausnahmen innerhalb der Schleife

for (Future<String> r : returns) { 
    try { 
     String temp = r.get(); 
     System.out.println("returned " + temp); 
    } catch (InterruptedException e) { 
     System.out.println("Interrupted Exception catch"); 
     e.printStackTrace(); 
    } catch (ExecutionException e) { 
     System.out.println("Execution Exception catch"); 
     e.printStackTrace(); 
    } 
} 
+0

Dank dafür, als ein relativer Neuling auf Java (von Cobol aller Dinge), wo der Versuch/Fang ist nicht immer offensichtlich – Anthony

0

Andere Lösung:

Aufschalten afterExecute Methode in ThreadPoolExecutor

protected void afterExecute(Runnable r, 
       Throwable t) 

Methode, die nach Abschluss der Ausführung der angegebenen Runnable aufgerufen wird. Diese Methode wird vom Thread aufgerufen, der die Aufgabe ausgeführt hat. Wenn nicht-null, ist Throwable die nicht erfasste RuntimeException oder Error, die die Ausführung abrupt beendet hat.

Beispielcode aus der Oracle-Dokumentation Link:

class ExtendedExecutor extends ThreadPoolExecutor { 
    // ... 
    protected void afterExecute(Runnable r, Throwable t) { 
    super.afterExecute(r, t); 
    if (t == null && r instanceof Future<?>) { 
     try { 
     Object result = ((Future<?>) r).get(); 
     } catch (CancellationException ce) { 
      t = ce; 
     } catch (ExecutionException ee) { 
      t = ee.getCause(); 
     } catch (InterruptedException ie) { 
      Thread.currentThread().interrupt(); // ignore/reset 
     } 
    } 
    if (t != null) 
     System.out.println(t); 
    } 
}