Classe ExecutorService Java

ExecutorService est une interface centrale de la programmation concurrente Java, elle appartient aujava.util.concurrentpaquet.

ExecutorService offre une manière plus avancée de gérer les threads, permettant aux développeurs d'exécuter efficacement des tâches asynchrones sans créer et gérer manuellement des threads.

Les principales fonctions d'ExecutorService incluent :

  • Gestion du pool de threads: Gérer automatiquement le cycle de vie des threads, en réduisant la surcharge de création et de destruction des threads.
  • Planification des tâches: Prend en charge la soumission deRunnableouCallabletâches, et renvoieFuturedes objets pour suivre l'état d'exécution des tâches.
  • Optimisation des ressources: Réutiliser les threads via le pool de threads pour améliorer les performances du système.

Méthodes principales d'ExecutorService

ExecutorService fournit plusieurs méthodes pour soumettre, gérer et contrôler l'exécution des tâches. Voici quelques méthodes clés :

submit()

Utilisé pour soumettre une tâche (RunnableouCallable) et renvoieFutureobjet pour vérifier si la tâche est terminée ou pour obtenir la valeur de retour.

Exemple

ExecutorService executor = Executors.newFixedThreadPool(2);
Future<?> future = executor.submit(() -> {
    System.out.println("La tâche est en cours d'exécution");
});

execute()

Sert uniquement à soumettreRunnabledes tâches, sans renvoyer de résultat.

Exemple

executor.execute(() -> {
    System.out.println("Tâche exécutée");
});

shutdown()

Arrête proprement le pool de threads, n'accepte plus de nouvelles tâches, mais attend que les tâches déjà soumises se terminent.

Exemple

executor.shutdown();

shutdownNow()

Arrête immédiatement le pool de threads, tente d'interrompre toutes les tâches en cours d'exécution et renvoie la liste des tâches qui n'ont pas été exécutées.

Exemple

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

awaitTermination()

Attends que le pool de threads s'arrête jusqu'à ce que toutes les tâches soient terminées ou qu'un délai d'attente soit écoulé.

Exemple

executor.awaitTermination(10, TimeUnit.SECONDS);

Comment créer un ExecutorService

Java fournitExecutorsclasse utilitaire pour créer différents types de pools de threads :

newFixedThreadPool(int nThreads)

Crée un pool de threads à taille fixe, adapté aux tâches à charge stable.

Exemple

ExecutorService fixedThreadPool = Executors.newFixedThreadPool(4);

newCachedThreadPool()

Crée un pool de threads mis en cache, adapté aux tâches asynchrones de courte durée.

Exemple

ExecutorService cachedThreadPool = Executors.newCachedThreadPool();

newSingleThreadExecutor()

Créer un pool de threads à un seul thread, adapté aux tâches exécutées séquentiellement.

Exemple

ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();

newScheduledThreadPool(int corePoolSize)

Créer un pool de threads qui prend en charge les tâches planifiées ou périodiques.

Exemple

ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(2);

Exemples d'utilisation

Soumission de tâches Runnable

Exemple

ExecutorService executor = Executors.newFixedThreadPool(2);

executor.submit(() -> {
    System.out.println("Tâche 1 en cours d'exécution");
});

executor.submit(() -> {
    System.out.println("Tâche 2 en cours d'exécution");
});

executor.shutdown();

Soumission de tâches Callable et obtention des résultats

Exemple

ExecutorService executor = Executors.newFixedThreadPool(2);

Future<String> future = executor.submit(() -> {
    Thread.sleep(1000);
    return "Tâche terminée";
});

try {
    String result = future.get(); // Bloque jusqu'à ce que la tâche se termine
    System.out.println(result);
} catch (Exception e) {
    e.printStackTrace();
}

executor.shutdown();

Bonnes pratiques

  1. Définir raisonnablement la taille du pool de threads:

    • Tâches gourmandes en CPU :线程数 = CPU 核心数 + 1
    • Tâches gourmandes en E/S :线程数 = CPU 核心数 * 2
  2. Éviter les fuites de mémoire:

    • Assurez-vous d'appelershutdown()oushutdownNow()pour arrêter le pool de threads.
  3. Gérer les exceptions:

    • Utilisertry-catchpour intercepter les exceptions dans les tâches, en empêchant les threads de se terminer de manière inattendue.
  4. UtiliserFuturepour gérer les tâches:

    • ViaFuture.get()obtenir les résultats des tâches ou vérifier l'état des tâches.
Autres extensions