Heim >Java >javaLernprogramm >Wie kann ich effizient warten, bis alle Aufgaben in einem ExecutorService abgeschlossen sind?

Wie kann ich effizient warten, bis alle Aufgaben in einem ExecutorService abgeschlossen sind?

Mary-Kate Olsen
Mary-Kate OlsenOriginal
2024-12-10 16:01:11866Durchsuche

How Can I Efficiently Wait for All Tasks to Complete in an ExecutorService?

ExecutorService: Warten auf Aufgabenabschluss

ExecutorService ist ein praktisches Tool für die effiziente Aufgabenausführung, aber eine Pause, bis alle Aufgaben abgeschlossen sind, kann schwierig sein. Lassen Sie uns auf ein häufiges Problem und seine praktische Lösung eingehen.

Fehler in wait()

Das zitierte Code-Snippet, das einen ExecutorService mit festem Thread-Pool verwendet, erlebt eine IllegalMonitorStateException beim Versuch, es.wait() zu verwenden. Dies liegt daran, dass wait() für die Verwendung mit bestimmten Thread-Synchronisations-Idiome gedacht ist, nicht mit ExecutorService.

Einfachste Lösung: invokeAll()

ExecutorService bietet eine einfachere Alternative für Zu diesem Zweck: invokeAll(). Diese Methode nimmt eine Sammlung aufrufbarer Aufgaben, führt sie parallel aus und blockiert, bis alle Aufgaben abgeschlossen sind. So verwenden Sie es:

ExecutorService es = Executors.newFixedThreadPool(2);
List<Callable<Object>> todo = new ArrayList<>(uniquePhrases.size());

for (DataTable singleTable: uniquePhrases) { 
    todo.add(Executors.callable(new ComputeDTask(singleTable))); 
}

List<Future<Object>> answers = es.invokeAll(todo);

invokeAll() gibt eine Liste von Future-Objekten zurück, die jeweils eine einzelne Aufgabe darstellen. Sobald alle Aufgaben abgeschlossen sind, wird beim Zugriff auf isDone() eines Futures „true“ zurückgegeben.

Vorteile von invokeAll()

  • Blockiert, bis alle Aufgaben abgeschlossen sind.
  • Vermeidet manuelles Herunterfahren und Synchronisieren.
  • Ermöglicht die Wiederverwendung von ExecutorService für mehrere Aufgaben Zyklen.

Andere Methoden

  • shutdown() undawaitTermination() können ebenfalls verwendet werden, erfordern jedoch eine manuelle Abschaltbehandlung.
  • submit(Callable) kann für die Übermittlung einzelner Aufgaben verwendet werden, erfordert jedoch eine manuelle Verfolgung der Aufgabe Fertigstellung.

Denken Sie daran, dass invokeAll() erfordert, dass Ihre Aufgaben Callable implementieren. Wenn es sich bei ComputeDTask um eine ausführbare Datei handelt, umschließen Sie sie wie im Codeausschnitt gezeigt oder verwenden Sie Executors.callable().

Das obige ist der detaillierte Inhalt vonWie kann ich effizient warten, bis alle Aufgaben in einem ExecutorService abgeschlossen sind?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn