2017-04-07 4 views
0

Ich verwende ExecutorCompletionService, um das Ergebnis der Aufträge zu erhalten, sobald es seine Ausführung beendet. Pseudo-Code ist wie this-
Korrekte Weise, Ausgabe von ExecutorCompletionService zu erhalten

Instantiate FixedThreadPool executor, exec 
Instantiate ExecutorCompletionService, completionService 
for(taskList) { 
    completionService.submit(someTask) 
} 
exec.shutDown(); 
whie(!exec.isShutdown()) { //Line 1 
    Task t = completionService.take(); //Line 2 
} 

Wie wir wissen, shutdown() wartet auf die Beendigung aller eingereichten Aufgaben, so lange, wie es eine Aufgabe im Gange ist, während Zustand auf Line1 gibt true zurück und Code geht in der Schleife um die abgeschlossene Aufgabe aus der Warteschlange zu übernehmen und gegebenenfalls zu warten.
Jetzt habe ich ein Problem mit dem obigen Code beobachtet, in dem Kontrolle auf Linie2 blockiert wird, selbst wenn keine weiteren Aufgaben mehr im Gange sind, alle Aufgaben abgeschlossen wurden.
Ich denke, es ist, weil ThreadPoolExecutor den Shutdown-Prozess wieder aufnimmt, wenn die letzte Aufgabe abgeschlossen und der Abschlusswarteschlange hinzugefügt wird, da es keine ausstehenden gesendeten Aufgaben mehr gibt. Aber während es noch heruntergefahren wurde, findet die nächste Iteration statt und isShutdown() gibt false zurück, so dass es in die Schleife geht und durch den take() Aufruf blockiert wird, obwohl keine weiteren Aufgaben vorhanden sind. Vielleicht ist es die Zeit zwischen dem letzten Anruf und dem richtigen Pool. Denke ich in die richtige Richtung?
Also habe ich überlegt, ob dies der richtige Weg ist, um das Ergebnis vom Completion Service zu nutzen? Um dies zu beheben, kann ich die while on line1 durch for(taskList) ersetzen, um isShutdown Anruf zu vermeiden. Es gibt noch eine andere Sache, ist es die beste Praxis, den Executor herunterzufahren und dann das Ergebnis vom Completion-Service zu bekommen oder zuerst das Ergebnis zu sammeln und am Ende den execturo herunterzufahren?

Antwort

0

Versuchen isTerminated() statt isShutoown() zu verwenden. Aber die beste Wahl wird sein, awaistTermination() Methode zu verwenden, anstatt diese Schleife zu erstellen.

Verwandte Themen