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 submittingRunnableoderCallablevon 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

ExecutorService executor = Executors.newFixedThreadPool(2);
Future<?> future = executor.submit(() -> {
    System.out.println("Task is running");
});

execute()

Wird nur zum Einreichen vonRunnableAufgaben verwendet, ohne Ergebnisse zurückzugeben.

Beispiel

executor.execute(() -> {
    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

executor.shutdown();

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

List<Runnable> notExecutedTasks = executor.shutdownNow();

awaitTermination()

Warten Sie auf das Herunterfahren des Thread-Pools, bis alle Aufgaben abgeschlossen sind oder eine Zeitüberschreitung auftritt.

Beispiel

executor.awaitTermination(10, TimeUnit.SECONDS);

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

ExecutorService fixedThreadPool = Executors.newFixedThreadPool(4);

newCachedThreadPool()

Erstellen Sie einen Cache-Thread-Pool, geeignet für kurzlebige asynchrone Aufgaben.

Beispiel

ExecutorService cachedThreadPool = Executors.newCachedThreadPool();

newSingleThreadExecutor()

Erstellen Sie einen Thread-Pool mit einem einzelnen Thread, geeignet für Aufgaben, die sequenziell ausgeführt werden.

Beispiel

ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();

newScheduledThreadPool(int corePoolSize)

Erstellen Sie einen Thread-Pool, der geplante oder periodische Aufgaben unterstützt.

Beispiel

ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(2);

Anwendungsbeispiele

Runnable-Aufgaben übermitteln

Beispiel

ExecutorService executor = Executors.newFixedThreadPool(2);

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

ExecutorService executor = Executors.newFixedThreadPool(2);

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

  1. Thread-Pool-Größe angemessen festlegen:

    • CPU-intensive Aufgaben:线程数 = CPU 核心数 + 1
    • IO-intensive Aufgaben:线程数 = CPU 核心数 * 2
  2. Speicherlecks vermeiden:

    • Achten Sie darauf, aufzurufenshutdown()odershutdownNow()um den Thread-Pool herunterzufahren.
  3. Ausnahmen behandeln:

    • Verwenden Sietry-catchum Ausnahmen in Aufgaben abzufangen und zu verhindern, dass Threads unerwartet beendet werden.
  4. Verwenden SieFutureum Aufgaben zu verwalten:

    • DurchFuture.get()Aufgabenergebnisse abrufen oder den Aufgabenstatus überprüfen.
Andere Erweiterungen