Top 40 des questions et réponses d'entretien sur le multithreading Java – Édition 2026

Se préparer à un entretien multithread Java nécessite une compréhension approfondie des concepts de concurrence et une expérience pratique. Vous trouverez ci-dessous 40 questions soigneusement conçues et réponses d'experts qui couvrent tout, des définitions de base aux sujets avancés tels que les fils de discussion virtuels et la concurrence structurée.
👉 Téléchargement PDF gratuit :Questions et réponses d'entretien multithreading Java
1) Qu'est-ce que le multithreading en Java et pourquoi est-il utilisé ?
Le multithreading permet à une application Java d'exécuter plusieurs threads simultanément, maximisant l'utilisation du processeur et améliorant la réactivité. Il est particulièrement utile pour les tâches liées aux E/S, les calculs à grande échelle et les mises à jour de l'interface graphique où un thread peut se bloquer tandis qu'un autre continue de traiter.
Avantages
- Utilisation accrue du processeur
- Latence réduite pour les opérations indépendantes
- Réactivité améliorée de l'interface utilisateur
Exemple :Un serveur Web peut gérer des dizaines de requêtes client simultanément en attribuant chaque requête à un thread distinct, évitant ainsi le blocage des opérations d'E/S.
2) Expliquer le cycle de vie d'un thread en Java.
Les threads Java progressent dans les états suivants :
| État | Description |
|---|---|
| Nouveau | Thread créé mais pas encore démarré. |
| Exécutable | Le thread est prêt à être exécuté ou est en cours d'exécution. |
| Bloqué | Le thread attend un verrouillage du moniteur. |
| En attente | Le thread attend indéfiniment le signal d'un autre thread. |
| Attente chronométrée | Le thread attend pendant une durée spécifiée. |
| Terminé | Le thread a terminé son exécution. |
Quand t.start() est invoqué, le thread passe de Nouveau à Exécutable .
3) Quelle est la différence entre un processus et un thread ?
| Critères | Processus | Thème |
|---|---|---|
| Mémoire | Propre espace d'adressage | Partage la mémoire du processus |
| Communication | Nécessite IPC | Partage directement la mémoire |
| Coût de création | Cher | Léger |
| Impact des échecs | Isolé | Peut affecter les frères et sœurs |
Par exemple, un processus de navigateur peut contenir plusieurs threads pour le rendu, la mise en réseau et l'interaction de l'utilisateur.
4) Comment fonctionne la synchronisation en Java ?
La synchronisation garantit qu'un seul thread accède à une ressource partagée à la fois, évitant ainsi les conditions de concurrence critique et la corruption des données. Le synchronized Le mot-clé verrouille soit une méthode entière, soit un bloc spécifique.
- Méthode synchronisée – verrouille le moniteur de la méthode.
- Blocage synchronisé – verrouille un objet choisi.
synchronized void increment() {
count++;
}
5) Quelles sont les différentes manières de créer un thread en Java ?
- Extension
Threadclass MyThread extends Thread { public void run() { System.out.println("Thread running"); } } new MyThread().start(); - Mise en œuvre de
Runnableclass MyRunnable implements Runnable { public void run() { System.out.println("Runnable running"); } } new Thread(new MyRunnable()).start(); - Appelable et futur (moderne) – renvoie une valeur et peut lancer des exceptions vérifiées.
Callable
task = () -> 42; Future result = executor.submit(task); System.out.println(result.get());
6) Quelle est la différence entre start() et run() ?
| Aspect | start() | run() |
|---|---|---|
| Création de fil de discussion | Crée un nouveau thread de système d'exploitation | S'exécute dans le thread actuel |
| Invocation | Planifie le thread dans la JVM | Appel de méthode simple |
| Concurrence | Exécution asynchrone | Exécution séquentielle |
Appel au t.start() lance un nouveau fil de discussion ; t.run() se comporte comme n'importe quelle autre méthode.
7) Expliquez le concept de sécurité des threads et comment y parvenir.
La sécurité des threads garantit que l’accès simultané aux données partagées ne corrompt pas l’état. Cela peut être réalisé via :
synchronizedblocs ou méthodesvolatilevariable- Verrous explicites (par exemple,
ReentrantLock,ReadWriteLock) - Collections Thread Safe (
ConcurrentHashMap,CopyOnWriteArrayList) - Classes atomiques (
AtomicInteger,AtomicBoolean)
AtomicInteger counter = new AtomicInteger(); counter.incrementAndGet();
8) Quelle est la différence entre wait() , sleep() , et yield() ?
| Méthode | Classe | Déverrouillage | Objectif | Durée |
|---|---|---|---|---|
wait() | Objet | Oui | Attendez la notification | Jusqu'à notification |
sleep() | Thème | Non | Suspendre l'exécution | Heure fixe |
yield() | Thème | Non | Suggérer un changement de planificateur | Imprévisible |
Utilisez wait() pour la communication inter-thread ; utilisez sleep() pour mettre un fil de discussion en pause.
9) Comment Executor Framework améliore-t-il la gestion des threads ?
Le framework dissocie la soumission des tâches de la création de threads, permettant un regroupement de threads efficace et une réutilisation des ressources. Il fait partie de java.util.concurrent et propose :
- Réutilisation des threads pour réduire les frais généraux
- Types de pools flexibles (fixe, mis en cache, unique, planifié, vol de travail)
- Mécanismes d'arrêt progressifs
ExecutorService executor = Executors.newFixedThreadPool(5);
executor.submit(() -> System.out.println("Task executed"));
executor.shutdown(); 10) Quels sont les différents types de pools de threads disponibles en Java ?
| Type de pool | Méthode d'usine | Description |
|---|---|---|
| FixedThreadPool | newFixedThreadPool(n) | Nombre fixe de threads |
| Pool de threads mis en cache | newCachedThreadPool() | Crée les threads selon les besoins, en réutilisant ceux inactifs |
| SingleThreadExecutor | newSingleThreadExecutor() | Thread de travail unique pour une exécution séquentielle |
| Pool de threads planifié | newScheduledThreadPool(n) | Prend en charge les tâches retardées ou périodiques |
| WorkStealingPool | newWorkStealingPool() | Utilise dynamiquement les processeurs disponibles |
11) Qu'est-ce qu'un blocage en Java et comment peut-il être évité ?
Un blocage se produit lorsque deux threads ou plus attendent indéfiniment que l'autre libère les verrous. Cela provient généralement d'un ordre de verrouillage incohérent.
synchronized (A) {
synchronized (B) { /*...*/ }
}
synchronized (B) {
synchronized (A) { /*...*/ }
}
Stratégies de prévention :
- Acquérir les verrous dans un ordre global cohérent.
- Utilisez
tryLock()avec un délai d'attente. - Évitez les verrous imbriqués lorsque cela est possible.
- Préférez les utilitaires de concurrence de haut niveau aux verrous manuels.
12) Différence entre synchronized et ReentrantLock .
| Fonctionnalité | synchronized | Verrouillage réentrant |
|---|---|---|
| Acquisition | Implicite | Explicite via lock() |
| Déverrouillage | Automatique à la sortie de la méthode | Manuel via unlock() |
| Essayer/Délai d'attente | Non disponible | Prend en charge tryLock() et délai d'attente |
| Équité | Non configurable | Prend en charge les commandes équitables |
| Variables de condition | Non pris en charge | Prend en charge plusieurs Condition objets |
ReentrantLock lock = new ReentrantLock();
if (lock.tryLock(1, TimeUnit.SECONDS)) {
try { /* critical section */ } finally { lock.unlock(); }
} 13) Différence entre volatile et synchronized .
| Aspect | volatile | synchronisé |
|---|---|---|
| Objectif | Visibilité | Atomicité + visibilité |
| Atomicité | Aucune garantie | Garanti |
| Verrouillage | Non | Oui |
| Cas d'utilisation | Drapeaux simples | Opérations composées |
volatile boolean running = true;
synchronized void increment() { count++; } 14) Expliquez ThreadLocal en Java.
ThreadLocal fournit des données spécifiques au thread, éliminant ainsi le besoin d'un état mutable partagé. Chaque thread accède à sa propre copie isolée.
ThreadLocalcounter = ThreadLocal.withInitial(() -> 0); counter.set(counter.get() + 1);
- Empêche la corruption des données
- Utile pour le contexte par thread (par exemple, les ID de session)
- Vous devez appeler le
remove()dans les pools de threads pour éviter les fuites de mémoire
15) Que sont les classes atomiques en Java et pourquoi sont-elles utilisées ?
Classes atomiques (par exemple, AtomicInteger , AtomicBoolean , AtomicReference ) effectuent des opérations thread-safe sans verrouillage à l’aide de CAS (Compare-And-Swap). Ils offrent un débit plus élevé pour les mises à jour simples par rapport aux blocs synchronisés.
AtomicInteger counter = new AtomicInteger(); counter.incrementAndGet();
16) Qu'est-ce qu'un sémaphore et en quoi diffère-t-il d'un verrou ?
| Aspect | Sémaphore | Verrouiller |
|---|---|---|
| Objectif | Limiter les accès simultanés | Exclusion mutuelle |
| Permis | Plusieurs | Célibataire |
| Blocage | Acquiert le permis | Acquiert la propriété |
| Cas d'utilisation | Regroupement de connexions | Protection des sections critiques |
Semaphore sem = new Semaphore(3); sem.acquire(); // use resource sem.release();
17) Expliquez le framework Fork/Join.
Introduit dans Java 7, il permet l'exécution parallèle de tâches fractionnables de manière récursive à l'aide d'un algorithme de vol de travail. Les threads inactifs volent le travail des threads occupés, maximisant ainsi l'utilisation du processeur.
class SumTask extends RecursiveTask{ protected Integer compute() { if (end - start <= threshold) return computeDirectly(); int mid = (start + end) / 2; SumTask left = new SumTask(start, mid); SumTask right = new SumTask(mid, end); left.fork(); return right.compute() + left.join(); } }
18) Comment CompletableFuture améliore-t-il la programmation asynchrone ?
CompleteableFuture permet des opérations asynchrones non bloquantes et composables, éliminant l'enfer des rappels et prenant en charge le chaînage, la gestion des exceptions et la composition parallèle.
CompletableFuture.supplyAsync(() -> "Hello")
.thenApply(str -> str + " World")
.thenAccept(System.out::println); 19) Qu'est-ce qu'un thread démon ?
Les threads démons s'exécutent en arrière-plan, fournissant des services tels que le garbage collection ou les tâches de minuterie. La JVM met automatiquement fin à tous les threads du démon lorsqu'il ne reste aucun thread utilisateur.
Thread daemon = new Thread(() -> System.out.println("Daemon running"));
daemon.setDaemon(true);
daemon.start(); 20) Meilleures pratiques pour le multithreading en Java.
- Préférez les utilitaires de simultanéité de haut niveau (ExecutorService, BlockingQueue).
- Évitez l'état mutable partagé ; privilégier l'immuabilité.
- Utilisez des collections simultanées sur des wrappers synchronisés.
- Gérez correctement les interruptions et restaurez l'indicateur d'interruption.
- Arrêtez les exécuteurs en douceur avec
shutdown()oushutdownNow(). - Réduire la portée de la synchronisation pour réduire les conflits.
- Profil avant l'optimisation ; des outils tels que JFR et async‑profiler aident à identifier les points chauds.
21) Qu'est-ce que le modèle de mémoire Java (JMM) et pourquoi est-il important ?
Le JMM définit la manière dont les threads interagissent via la mémoire, garantissant la visibilité, l'ordre et l'atomicité. Il établit la relation qui se produit avant, ce qui est essentiel pour écrire du code concurrent correct.
- Visibilité :les modifications apportées par un fil de discussion doivent être vues par les autres.
- Ordre :les actions sont ordonnées pour préserver la cohérence.
- Atomicité :certaines opérations sont indivisibles.
22) Différence entre ConcurrentHashMap et synchroniséMap.
| Fonctionnalité | ConcurrentHashMap | Carte synchronisée |
|---|---|---|
| Verrouillage de la granularité | Niveau segment (partiel) | Carte entière |
| Performances contestées | Élevé | Faible |
| Clés/valeurs nulles | Non autorisé | Autorisé |
| Cohérence des itérateurs | Faiblement cohérent | Échec rapide |
| Lectures simultanées | Autorisé | Bloqué |
23) Détection et débogage des blocages.
- Dumps de threads via
jstack <pid>révéler des impasses. - VisualVM ou JConsole assurent la surveillance des threads en temps réel.
- Détection programmatique avec
ThreadMXBean.findDeadlockedThreads().
24) Flux parallèles et threads explicites.
Les flux parallèles utilisent en interne le framework Fork/Join, offrant une API de haut niveau pour le traitement des données. Les threads explicites nécessitent une gestion manuelle mais offrent un contrôle précis.
| Aspect | Flux parallèles | Fils |
|---|---|---|
| Abstraction | API de haut niveau | Contrôle de bas niveau |
| Gestion | Automatique via ForkJoinPool | Pool de threads manuel |
| Réglage | Utilise le pool commun | Taille du pool personnalisée |
| Gestion des erreurs | Limité | Contrôle total |
25) CountDownLatch, CyclicBarrier et Phaser.
| Fonctionnalité | CountDownLatch | Barrière cyclique | Phaseur |
|---|---|---|---|
| Réinitialiser | Non | Oui | Oui |
| Fêtes | Corrigé | Corrigé | Dynamique |
| Cas d'utilisation | Attendez la fin des tâches | Sujets à rencontrer | Coordination dynamique |
CountDownLatch latch = new CountDownLatch(3);
for (...) new Thread(() -> { /* work */ latch.countDown(); }).start();
latch.await(); 26) Différence entre Callable et Runnable.
| Aspect | Exécutable | Rappelable |
|---|---|---|
| Valeur de retour | Non | Oui |
| Exceptions vérifiées | Non | Oui |
| Package | java.lang | java.util.concurrent |
Callabletask = () -> 42; Future result = executor.submit(task); System.out.println(result.get());
27) BlockingQueue pour producteur-consommateur.
BlockingQueue propose des opérations de blocage thread-safe qui simplifient le modèle producteur-consommateur.
BlockingQueuequeue = new ArrayBlockingQueue<>(10); new Thread(() -> queue.put(1)).start(); // Producer new Thread(() -> System.out.println(queue.take())).start(); // Consumer
- Élimine le manuel
wait()/notify(). - Prend en charge les implémentations limitées et illimitées.
28) Manque de threads et livelock.
La famine se produit lorsque les threads de faible priorité ne reçoivent jamais de temps CPU. Livelock se produit lorsque les threads changent continuellement d'état mais ne progressent pas. L'atténuation comprend des verrouillages équitables, en évitant les attentes chargées et une planification appropriée.
29) Amélioration des performances des applications multithread.
- Utilisez des pools de threads.
- Réduire la portée de la synchronisation.
- Exploitez les structures de données concurrentes.
- Préférez les objets immuables.
- Évitez les faux partages.
- Ajustez le nombre de threads en fonction des cœurs du processeur.
- Utilisez des E/S asynchrones pour bloquer les opérations.
30) Scénario multithread réel.
Dans une passerelle de paiement, le traitement simultané des transactions a été optimisé par :
- ExecutorService pour les threads de travail.
- ConcurrentHashMap pour l'état de la transaction.
- ReentrantLock pour le verrouillage au niveau du compte.
- CountDownLatch pour la synchronisation par lots.
- CompletableFuture pour les réponses asynchrones.
Résultat :35 % de gain de débit et 40 % de réduction de latence.
31) Threads virtuels en Java.
Les threads virtuels, introduits dans Java 21, sont des threads légers gérés par la JVM, permettant des millions de tâches simultanées avec une surcharge minimale.
| Fonctionnalité | Fils de discussion de la plateforme | Fils virtuels |
|---|---|---|
| Géré par | OS | JVM |
| Coût de création | Élevé | Très faible |
| Niveau de concurrence | Des milliers | Des millions |
| Planification | Niveau du système d'exploitation | Coopérative JVM |
| Cas d'utilisation | Tâches liées au processeur | Tâches liées aux E/S/à haute concurrence |
Thread.startVirtualThread(() -> System.out.println("Virtual thread running")); 32) Concurrence structurée.
Présentée en avant-première dans Java 21, la simultanéité structurée traite plusieurs tâches simultanées comme une seule unité, garantissant qu'elles sont démarrées, gérées et terminées ensemble. Il élimine les threads orphelins et simplifie la propagation des erreurs.
try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {
Future user = scope.fork(() -> findUser());
Future order = scope.fork(() -> fetchOrderCount());
scope.join();
scope.throwIfFailed();
System.out.println(user.resultNow() + " has " + order.resultNow() + " orders.");
} 33) Flux réactifs en Java.
Les flux réactifs fournissent un modèle non bloquant et sensible à la contre-pression pour gérer les flux de données, constituant la base de frameworks tels que Project Reactor, RxJava et Spring WebFlux.
Publisher– produit des données.Subscriber– consomme des données.Subscription– contrôle le flux.Processor– à la fois éditeur et abonné.
Flow.Publisherpublisher = subscriber -> subscriber.onNext(42);
34) Gestion appropriée des interruptions de thread.
Cochez toujours Thread.interrupted() en boucles, nettoie les ressources et préserve l'état de l'interruption après avoir attrapé InterruptedException .
while (!Thread.currentThread().isInterrupted()) {
try { Thread.sleep(1000); }
catch (InterruptedException e) {
Thread.currentThread().interrupt(); // restore flag
break;
}
} 35) Parallélisme vs concurrence.
La concurrence gère plusieurs tâches en entrelaçant l'exécution, tandis que le parallélisme exécute les tâches simultanément sur plusieurs cœurs de processeur.
| Concept | Définition | Exemple |
|---|---|---|
| Concurrence | Tâches entrelacées | Traitement simultané de 1 000 demandes clients |
| Parallélisme | Exécution simultanée | Exécuter des calculs sur les cœurs du processeur |
36) Outils et techniques de profilage de threads.
| Outil | Objectif |
|---|---|
| jstack | Capture de vidage de thread |
| jconsole / VisualVM | Surveillance en temps réel |
| Enregistreur de vol Java (JFR) | Profilage à faible surcharge |
| Contrôle de mission (JMC) | Visualisation des enregistrements JFR |
| profileur asynchrone | Profilage du processeur et des allocations |
| ThreadMXBean | Inspection programmatique |
ThreadMXBean bean = ManagementFactory.getThreadMXBean(); System.out.println(bean.getThreadCount());
37) Goulots d'étranglement courants en matière de performances.
- Conflit excessif de verrous.
- Faux partage de variables.
- Surcharge de changement de contexte.
- Synchronisation incorrecte.
- Surutilisation des variables volatiles.
Les optimisations incluent un verrouillage à granularité fine, des structures sans verrouillage, une réduction de la création de threads et l'utilisation du stockage local des threads.
38) Algorithmes sans verrouillage, sans attente et sans obstruction.
| Type | Définition | Garantie |
|---|---|---|
| Sans verrouillage | Au moins un fil de discussion progresse. | Progrès à l'échelle du système. |
| Sans attente | Chaque thread progresse par étapes délimitées. | Garantie la plus solide. |
| Sans obstruction | Progrès en l'absence de contention. | Garantie la plus faible. |
Les opérations AtomicInteger sont sans verrouillage ; les files d'attente bloquantes utilisent des verrous.
39) Éléments internes de ForkJoinPool.
Chaque travailleur entretient son propre deque ; les travailleurs inactifs volent les tâches des autres, réduisant ainsi les conflits et améliorant le débit.
ForkJoinPool pool = new ForkJoinPool(); pool.submit(() -> IntStream.range(0, 100).parallel().forEach(System.out::println));
40) Concevoir un système hautement concurrent pour des millions de requêtes.
- Threads virtuels pour une gestion légère des requêtes.
- Flux réactifs pour les E/S asynchrones.
- Concurrence structurée pour des cycles de vie de tâches prévisibles.
- Caches hautes performances (ConcurrentHashMap, Caffeine).
- Files d'attente Thread Safe (Disruptor, BlockingQueue).
- Surveillance avec JFR et JMC.
- CompletableFuture pour les workflows asynchrones.
Résultat :obtenez des millions de connexions simultanées avec un blocage minimal et une utilisation optimale des ressources.
🔍 Principales questions d'entretien sur le multithreading Java avec des scénarios du monde réel et des réponses stratégiques
Vous trouverez ci-dessous dix questions réalistes, les attentes des enquêteurs et des exemples de réponses raffinées.
1) Différence entre un processus et un thread en Java ?
Le candidat doit expliquer les principes fondamentaux du système d'exploitation et de la JVM, l'utilisation de la mémoire et le flux d'exécution. Par exemple, un processus de navigateur contient plusieurs threads pour le rendu, la mise en réseau et la saisie utilisateur.
2) Objet du synchronized mot-clé ?
Explique le contrôle de concurrence, les verrous intrinsèques et la sécurité des threads. Cela garantit qu'un seul thread accède à une section critique à la fois.
3) Un problème de multithreading difficile rencontré et résolu ?
Décrivez un scénario de blocage, comment vous l'avez identifié via des thread dumps et l'avez résolu en appliquant un ordre de verrouillage cohérent.
4) Modèle de mémoire Java et visibilité ?
Décrire les relations qui se produisent avant, volatile et des constructions de synchronisation qui garantissent la visibilité et l'ordre.
5) Différence entre wait() , notify() , et notifyAll() ?
Expliquer la communication entre les threads et les mécanismes de surveillance.
6) Optimiser une application multithread ?
Identifiez les conflits de verrouillage, remplacez synchronized avec ConcurrentHashMap , et affichez des gains de débit mesurables.
7) Mettre à jour en toute sécurité une structure de données partagée ?
Utilisez des collections thread-safe ou un verrouillage explicite avec ReentrantLock pour un contrôle granulaire.
8) Rôle de ExecutorService ?
Gère un pool de threads de travail, réduit les frais généraux et simplifie la gestion du cycle de vie.
9) Dépanner une condition de concurrence critique ?
Reproduisez sous charge, améliorez la journalisation et corrigez en ajoutant une synchronisation appropriée.
10) Concevoir une solution multithread avec des priorités variables ?
Utiliser une file d'attente prioritaire avec ThreadPoolExecutor et un comparateur personnalisé pour les tâches plus prioritaires.
Java
- Classe d'écriture Java
- Chaînes Java
- Java - Cadre de collections
- Java Math Abs() Round() Ceil() Floor() Min() Méthodes/Fonction avec exemple
- Types de données Java (primitifs)
- Java 8 - Nouvelle API Date/Heure
- Java - Classe de caractères
- Java 10 - Certificat racine
- Top 30 des questions et réponses d’entretien Eclipse (2026)