Java-ExecutorService-Klasse
ExecutorService ist eine Kernschnittstelle in der nebenläufigen Programmierung mit Java; sie gehört zumjava.util.concurrentdas Paket verwenden.
ExecutorService bietet eine fortgeschrittenere Art der Thread-Verwaltung, mit der Entwickler asynchrone Aufgaben effizient ausführen können, ohne Threads manuell erstellen und verwalten zu müssen.
Zu den Hauptfunktionen von ExecutorService gehören:
- Thread-Pool-Verwaltung: Automatische Verwaltung des Lebenszyklus von Threads, wodurch der Overhead für das Erstellen und Zerstören von Threads reduziert wird.
- Unterstützt das Übermitteln: Supports submitting
RunnableoderCallablevon Aufgaben und gibtFutureObjekte zurück, um den Ausführungsstatus von Aufgaben zu verfolgen. - Ressourcenoptimierung: Threads durch den Thread-Pool wiederverwenden, um die Systemleistung zu verbessern.
Kernmethoden von ExecutorService
ExecutorService bietet mehrere Methoden zum Einreichen, Verwalten und Steuern der Aufgabenausführung. Hier sind einige wichtige Methoden:
submit()
Wird verwendet, um eine Aufgabe einzureichen (RunnableoderCallable) und gibt einFutureObjekt zurück, mit dem überprüft werden kann, ob die Aufgabe abgeschlossen ist oder um den Rückgabewert abzurufen.
Beispiel
Future<?> future = executor.submit(() -> {
System.out.println("Task is running");
});
execute()
Wird nur zum Einreichen vonRunnableAufgaben verwendet, ohne Ergebnisse zurückzugeben.
Beispiel
System.out.println("Task executed");
});
shutdown()
Fährt den Thread-Pool ordnungsgemäß herunter, akzeptiert keine neuen Aufgaben mehr, wartet aber darauf, dass bereits eingereichte Aufgaben abgeschlossen werden.
Beispiel
shutdownNow()
Fährt den Thread-Pool sofort herunter, versucht, alle laufenden Aufgaben zu unterbrechen, und gibt die Liste der nicht ausgeführten Aufgaben zurück.
Beispiel
awaitTermination()
Warten Sie auf das Herunterfahren des Thread-Pools, bis alle Aufgaben abgeschlossen sind oder eine Zeitüberschreitung auftritt.
Beispiel
Wie man ExecutorService erstellt
Java bietetExecutorseine Hilfsklasse zum Erstellen verschiedener Arten von Thread-Pools:
newFixedThreadPool(int nThreads)
Erstellen Sie einen Thread-Pool mit fester Größe, geeignet für Aufgaben mit stabiler Last.
Beispiel
newCachedThreadPool()
Erstellen Sie einen Cache-Thread-Pool, geeignet für kurzlebige asynchrone Aufgaben.
Beispiel
newSingleThreadExecutor()
Erstellen Sie einen Thread-Pool mit einem einzelnen Thread, geeignet für Aufgaben, die sequenziell ausgeführt werden.
Beispiel
newScheduledThreadPool(int corePoolSize)
Erstellen Sie einen Thread-Pool, der geplante oder periodische Aufgaben unterstützt.
Beispiel
Anwendungsbeispiele
Runnable-Aufgaben übermitteln
Beispiel
executor.submit(() -> {
System.out.println("Task 1 running");
});
executor.submit(() -> {
System.out.println("Task 2 running");
});
executor.shutdown();
Callable-Aufgaben übermitteln und Ergebnisse abrufen
Beispiel
Future<String> future = executor.submit(() -> {
Thread.sleep(1000);
return "Task completed";
});
try {
String result = future.get(); // Blockiert, bis die Aufgabe abgeschlossen ist.
System.out.println(result);
} catch (Exception e) {
e.printStackTrace();
}
executor.shutdown();
Best Practices
Thread-Pool-Größe angemessen festlegen:
- CPU-intensive Aufgaben:
线程数 = CPU 核心数 + 1 - IO-intensive Aufgaben:
线程数 = CPU 核心数 * 2
- CPU-intensive Aufgaben:
Speicherlecks vermeiden:
- Achten Sie darauf, aufzurufen
shutdown()odershutdownNow()um den Thread-Pool herunterzufahren.
- Achten Sie darauf, aufzurufen
Ausnahmen behandeln:
- Verwenden Sie
try-catchum Ausnahmen in Aufgaben abzufangen und zu verhindern, dass Threads unerwartet beendet werden.
- Verwenden Sie
Verwenden Sie
Futureum Aufgaben zu verwalten:- Durch
Future.get()Aufgabenergebnisse abrufen oder den Aufgabenstatus überprüfen.
- Durch