ExecutorService et types de pools de threads
Créez des pools de threads fixes, mis en cache, à thread unique et planifiés, puis comprenez quand utiliser chacun d’eux.
ExecutorService et types de pools de threads est une leçon Java Academy gratuite sur CoddyKit. Ceci est la leçon 1 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage Java Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours Java Academy comprend 4 leçons au total.
Pourquoi utiliser des ensembles de fils d’exécution ?
Créer un nouveau Thread pour chaque tâche coûte cher : la création et la destruction d’un fil d’exécution entraînent une surcharge. Un ensemble de fils d’exécution réutilise un nombre fixe de fils pour exécuter de nombreuses tâches, ce qui réduit la surcharge et permet de contrôler la consommation de ressources.
import java.util.concurrent.*;
// Bad practice: new thread per task
new Thread(() -> System.out.println("task")).start();
// Better: reuse threads from a pool
ExecutorService pool = Executors.newFixedThreadPool(4);
pool.submit(() -> System.out.println("task from pool"));
pool.shutdown();newFixedThreadPool
Crée un ensemble comportant exactement N fils d’exécution. Les tâches supplémentaires sont placées en file d’attente jusqu’à ce qu’un fil devienne disponible. Convient lorsque vous connaissez le niveau de parallélisme souhaité.
ExecutorService pool = Executors.newFixedThreadPool(4);
for (int i = 0; i < 10; i++) {
final int taskId = i;
pool.submit(() -> {
System.out.println("Task " + taskId + " on " + Thread.currentThread().getName());
});
}
pool.shutdown();
pool.awaitTermination(10, TimeUnit.SECONDS);newCachedThreadPool
Crée des fils d’exécution à la demande et réutilise ceux qui sont inactifs. Les fils inactifs pendant 60 secondes sont arrêtés. Convient à de nombreuses tâches de courte durée ; risqué pour les tâches longues ou illimitées, car la mémoire peut être épuisée.
ExecutorService cached = Executors.newCachedThreadPool();
for (int i = 0; i < 100; i++) {
cached.submit(() -> {
// quick task
double result = Math.sqrt(Math.random());
});
}
cached.shutdown();newSingleThreadExecutor
Un ensemble comportant exactement un fil d’exécution. Les tâches s’exécutent séquentiellement dans l’ordre de leur soumission. Convient pour sérialiser l’accès à une ressource partagée.
ExecutorService single = Executors.newSingleThreadExecutor();
single.submit(() -> System.out.println("Task 1"));
single.submit(() -> System.out.println("Task 2"));
single.submit(() -> System.out.println("Task 3"));
// Always prints: Task 1, Task 2, Task 3 (sequential)
single.shutdown();newScheduledThreadPool
Prend en charge les tâches planifiées et récurrentes. À utiliser pour l’interrogation, les nouvelles tentatives et la maintenance en arrière-plan.
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(2);
// One-shot delay
scheduler.schedule(() -> System.out.println("Delayed!"),
3, TimeUnit.SECONDS);
// Fixed rate (every 2 seconds)
scheduler.scheduleAtFixedRate(
() -> System.out.println("Tick"),
0, 2, TimeUnit.SECONDS);
// Run later: scheduler.shutdown();VirtualThreadExecutor (Java 21+)
Java 21 introduit les fils virtuels, légers et peu coûteux à créer. Utilisez Executors.newVirtualThreadPerTaskExecutor() pour les charges de travail fortement orientées vers les entrées-sorties :
// Java 21+
try (var exec = Executors.newVirtualThreadPerTaskExecutor()) {
for (int i = 0; i < 10_000; i++) {
final int id = i;
exec.submit(() -> {
Thread.sleep(100); // blocks without tying up OS thread
System.out.println("vthread " + id);
});
}
} // auto-shutdownChoisir le bon ensemble
Recommandations :
- Tâches limitées par le CPU : ensemble fixe avec N = nombre de cœurs du
CPU - Tâches limitées par les entrées-sorties : ensemble mis en cache ou fils virtuels
- Tâches séquentielles : exécuteur à fil unique
- Tâches planifiées ou récurrentes : ensemble de fils planifiés
int cores = Runtime.getRuntime().availableProcessors();
ExecutorService cpuPool = Executors.newFixedThreadPool(cores);
System.out.println("Pool size: " + cores);ThreadPoolExecutor personnalisé
Pour un contrôle précis, créez directement un ThreadPoolExecutor :
ThreadPoolExecutor tpe = new ThreadPoolExecutor(
2, // corePoolSize
10, // maximumPoolSize
60L, // keepAliveTime
TimeUnit.SECONDS,
new LinkedBlockingQueue<>(100), // work queue
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.CallerRunsPolicy() // rejection policy
);
tpe.submit(() -> System.out.println("Custom pool task"));
tpe.shutdown();Arrêt progressif
Arrêtez toujours l’ExecutorService afin de libérer les fils d’exécution. shutdown() cesse d’accepter les nouvelles tâches, mais termine celles qui sont en file d’attente. shutdownNow() tente d’annuler les tâches en cours d’exécution.
ExecutorService pool = Executors.newFixedThreadPool(4);
// ... submit tasks ...
pool.shutdown(); // no new tasks
try {
if (!pool.awaitTermination(30, TimeUnit.SECONDS)) {
pool.shutdownNow(); // force cancel
}
} catch (InterruptedException e) {
pool.shutdownNow();
Thread.currentThread().interrupt();
}ExecutorService comme ressource refermable (Java 19+)
À partir de Java 19, ExecutorService implémente AutoCloseable. Utilisez la gestion automatique des ressources pour déclencher l’arrêt automatiquement :
// Java 19+ (preview), Java 21 stable
try (ExecutorService pool = Executors.newFixedThreadPool(4)) {
pool.submit(() -> System.out.println("task"));
} // pool.close() called: waits for tasks then shuts downPolitiques de rejet
Lorsque l’ensemble est saturé (tous les fils sont occupés et la file est pleine), la politique de rejet gère le dépassement :
- AbortPolicy (par défaut) : lève
RejectedExecutionException - CallerRunsPolicy : le fil appelant exécute la tâche
- DiscardPolicy : ignore silencieusement la tâche
- DiscardOldestPolicy : supprime la tâche la plus ancienne de la file
Vérification rapide
Vous avez une tâche limitée par le CPU qui effectue un calcul intensif. Combien de fils votre ensemble fixe doit-il comporter ?
Récapitulatif : ExecutorService et ensembles de fils d’exécution
Points essentiels :
- Ensemble fixe : N fils fixes ; les tâches supplémentaires sont mises en file
- Ensemble mis en cache : s’agrandit à la demande ; les fils inactifs expirent après 60 secondes
- Fil unique : l’ordre d’exécution séquentiel est garanti
- Ensemble planifié : tâches différées et récurrentes
- Appelez toujours
shutdown(); utilisezawaitTermination()pour une sortie propre
Questions Fréquemment Posées
La leçon « ExecutorService et types de pools de threads » est-elle gratuite ?
Oui — le texte complet de « ExecutorService et types de pools de threads » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours Java Academy, passe à CoddyKit PRO. Le cours Java Academy comprend 4 leçons au total.
Qu'est-ce que j'apprendrai dans « ExecutorService et types de pools de threads » ?
Créez des pools de threads fixes, mis en cache, à thread unique et planifiés, puis comprenez quand utiliser chacun d’eux. Tu pratiques Java Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.
Dois-je avoir de l'expérience pour commencer Java Academy ?
Aucune expérience préalable n'est requise. Java Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 1 sur 4.
Combien de temps prend la leçon « ExecutorService et types de pools de threads » ?
La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.
Peux-tu écrire et exécuter du code dans cette leçon Java Academy ?
Oui. Chaque leçon Java Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.
Toutes les leçons de ce cours
- ExecutorService et types de pools de threads
- Soumettre des tâches : Runnable et Callable
- Future et gestion des erreurs
- ScheduledExecutorService pour les tâches récurrentes