
FAQ Langage JavaConsultez toutes les FAQ
Nombre d'auteurs : 42, nombre de questions : 297, derni�re mise � jour : 19 septembre 2017 Ajouter une question
Cette FAQ a �t� r�alis�e � partir des questions fr�quemment pos�es sur le forum Java de http://java.developpez.com ainsi que l'exp�rience personnelle des auteurs.
Nous tenons � souligner que cette FAQ ne garantit en aucun cas que les informations qu'elle propose sont correctes. Les auteurs font leur maximum, mais l'erreur est humaine. Cette FAQ ne pr�tend pas non plus �tre compl�te. Si vous trouvez une erreur, ou que vous souhaitez nous aider en devenant r�dacteur, lisez ceci.
Sur ce, nous vous souhaitons une bonne lecture.
- Qu'est-ce qu'un thread ?
- Pourquoi toutes les m�thodes de la classe Thread sont-elles marqu�es � deprecated � ?
- Comment cr�er un thread ?
- Comment d�marrer un thread ?
- Comment terminer un thread sans la m�thode stop() ?
- Comment obtenir le thread courant ?
- Comment faire une � pause � dans mon application ?
- Comment changer la priorit� d'ex�cution d'un thread ?
- Pourquoi est-ce que mon programme ne s'arr�te pas � la fin du main() ?
- Comment cr�er un thread deamon ?
- Qu'est-ce que le double-check locking ?
- Comment avoir un Singleton s�r en environnement multi-thread ?
Un thread d�signe un ��fil d'ex�cution�� dans le programme�; c'est-�-dire une suite lin�aire et continue d'instructions qui sont ex�cut�es s�quentiellement les unes apr�s les autres. En fait, le langage Java est multi-thread, c'est-�-dire qu'il peut faire cohabiter plusieurs fils d�ex�cution de fa�on ind�pendante.
L'utilisation des threads est tr�s fr�quente dans la programmation r�seau. Un client FTP peut t�l�charger plusieurs fichiers, naviguer sur plusieurs serveurs en m�me temps, chaque connexion �tant g�r�e par un thread diff�rent. De m�me, un serveur FTP, doit g�n�ralement pouvoir traiter plusieurs clients connect�s en m�me temps�; sinon chaque client devrait patiemment attendre son tour, ce qui rendrait l'utilisation d'un tel serveur tr�s p�nible.
Les threads sont �galement tr�s utilis�s dans les applications disposant d'interfaces graphiques. Par exemple, dans un traitement de texte, un thread s'occupe de ce que saisit l'utilisateur, un autre est en charge de d�tecter les fautes d'orthographe et de grammaire, un autre se charge de l'impression du document dans une t�che de fond, etc.
Les programmes Java ont tous au moins un thread d�ex�cution qui est d�marr� lorsque la m�thode main() qui lance le programme est invoqu�e. De plus, la JVM peut g�n�rer des threads suppl�mentaires pour faire tourner le ramasse-miettes en t�che de fond. Les environnements graphiques fournis avec la JVM (AWT, Swing, JavaFX) disposent tous d'un ou plusieurs autres threads graphiques et/ou �v�nementiels qui se lancent � l'initialisation de ces environnements.
Pour mieux comprendre l'utilisation des threads, vous pouvez vous pencher sur ces deux tutoriels�:
-
Programmation des Threads en Java, premi�re partie par Val�re Viandier.
-
S�maphores et Mutex en Delphi et Java par Mathieu Dalbint.
Depuis le JDK�5, Java dispose aussi du package java.util.concurrent qui permet une meilleure gestion de la concurrence.
-
Comment cr�er un thread ?
-
Tutoriel : Programmation des Threads en Java par Val�re Viandier ;
-
Tutoriel : S�maphores et Mutex en Delphi et Java par Mathieu Dalbin ;
-
Package java.util.concurrent
Toutes ces m�thodes ont �t� marqu�es deprecated (d�pr�ci�es ou obsol�tes), car, sous certaines conditions et sans qu'il y ait d'erreur de conception, l'application peut se bloquer. Typiquement, lorsqu'un thread est tu� avec la m�thode stop(), il n'est pas possible de savoir ce qu'il �tait en train de faire, il est donc possible qu'il soit arr�t� au milieu d'une modification d'un objet�; cet objet est donc laiss� dans un �tat incoh�rent. Des probl�mes similaires peuvent se produire avec les m�thodes suspend() et resume().
Cr�er un thread est tr�s simple en Java. Plusieurs solutions s'offrent � vous.
java.lang.Thread
Vous pouvez cr�er une nouvelle classe qui d�rive de la classe java.lang.Thread. Il suffit ensuite de red�finir la m�thode run(). C'est cette m�thode que le thread va ex�cuter�:
Code Java : | S�lectionner tout |
1 2 3 4 5 6 7 8 | Thread tache = new Thread() { @Override public void run() { // Code � ex�cuter dans ce thread. [...] } } |
java.lang.Runnable
Si vous ne souhaitez pas faire une classe d�di�e � la gestion du processus, vous pouvez simplement impl�menter l'interface java.lang.Runnable et d�finir la m�thode run(). Ensuite il suffit de cr�er un objet java.lang.Thread en lui passant la classe en param�tre�:
Code Java : | S�lectionner tout |
1 2 3 4 5 6 7 8 9 10 | Runnable code = new Runnable() { @Override public void run() { // Code � ex�cuter. [...] } } // On place le code dans un nouveau thread. Thread tache = new Thread(code); |
Autres
Des frameworks graphiques tels que Swing ou JavaFX disposent de leurs propres outils pour cr�er des threads ou des t�ches de fond. Pensez � vous r�f�rer � la documentation ou aux didacticiels appropri�s pour savoir quelles classes utiliser dans ces environnements.
-
Comment d�marrer un thread ?
-
Comment terminer un thread sans la m�thode stop() ?
-
Comment lancer un traitement long ? (Swing) ;
-
Comment effectuer une t�che de fond ? (JavaFX) ;
-
Tutoriel : Programmation des Threads en Java par Val�re Viandier ;
-
Tutoriel : SwingWorker (Java SE 6) par Romain Vimont ;
-
Tutoriel : Ex�cution d'une t�che de fond en JavaFX par Fabrice Bouy�.
Pour lancer l'ex�cution d'un thread vous devez ex�cuter la m�thode start().
Code Java : | S�lectionner tout |
1 2 | Thread tache = [...] tache.start(); |
Avertissement�: vous ne devez en aucun cas ex�cuter vous-m�me la m�thode run(), car l'ex�cution se d�roulerait alors dans le processus courant�!
La m�thode stop() de la classe java.lang.Thread �tant d�pr�ci�e, il ne faut pas l'utiliser.
M�thode interrupt()
La mani�re la plus simple d�arr�ter un thread est d'invoquer la m�thode interrupt() de la classe java.lang.Thread. Cette m�thode a plusieurs effets possibles�:
- si votre thread �tait en train d'attendre ou de dormir (wait(), join(), sleep(), etc.), une exception de type java.lang.InterruptedException sera g�n�r�e dans le code � l'endroit o� cette attente a lieu�;
- si votre thread �tait en train d'effectuer un appel IO bloquant sur un canal, ce dernier sera ferm� et une exception de type java.nio.channels.ClosedByInterruptException sera g�n�r�e dans le code � l'endroit o� cette op�ration a lieu�;
- si votre thread est bloqu� dans un Selector, votre thread sera plac� dans l��tat interrupt et l�op�ration de s�lection retournera imm�diatement comme si la m�thode wakeup() avait �t� invoqu�e�;
- sinon, votre thread sera plac� dans l��tat interrupt et ses m�thodes interrupted() et isInterrupted() renverront la valeur true. Vous pouvez donc alors tester la valeur de retour de cette m�thode depuis votre code pour terminer la t�che pr�matur�ment ou faire des sauvegardes, fermetures de session, etc. si besoin avant de la quitter.
Dans le code appelant�:
Code Java : | S�lectionner tout |
1 2 3 4 | Thread tache = [...] tache.start(); [...] tache.interrupt(); |
Et dans la t�che�:
Code Java : | S�lectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | @Override public void run() { try { [...] // Si interrupt() est invoqu� alors que la t�che ex�cute cette portion du code, il suffit de tester l��tat du thread. if (isInterrupted()) { return; } [...] // Si interrupt() est invoqu� alors que la t�che dort suite � cet appel, une exception est g�n�r�e. sleep(500); [...] } (catch (InterruptedException ex) { // Traitement de l'erreur. } } |
Attention�:
- interrupted() est une m�thode statique qui agit sur le thread courant et remet � false l��tat interrupt du thread lors de son invocation�;
- isInterrupted() est une m�thode d'instance. Elle ne remet pas � false l��tat interrupt du thread lors de son invocation.
Autre
Si le thread est bloqu� sur une ressource, par exemple si votre t�che est en train d��couter sur un socket, invoquer interrupt() (ou m�me stop() ou m�me un s�maphore fait maison) n'aura aucun effet. Vous devrez donc fermer cette ressource (ici le socket) depuis un autre thread pour induire un �tat d'erreur dans votre code � l'endroit o� cette ressource est manipul�e.
Pour obtenir une r�f�rence sur le thread courant, c'est-�-dire celui qui est en train d�ex�cuter votre code, vous pouvez invoquer la m�thode statique currentThread() de la classe java.lang.Thread. Certaines m�thodes statiques de la classe Thread font d'ailleurs appel � cette m�thode pour manipuler le thread courant.
Code Java : | S�lectionner tout |
Thread courant = Thread.currentThread();
On peut simuler une pause dans l'ex�cution d'une application en utilisant la m�thode statique sleep() de la classe java.lang.Thread. Cette m�thode force le thread courant � cesser son ex�cution pendant le temps pass� en param�tre.
Par exemple�:
Code Java : | S�lectionner tout |
1 2 3 4 5 | long milliSecondes = 500L; int nanosSecondes = 6000; Thread.sleep(milliSecondes, nanosSecondes); // Ou�: Thread.sleep(milliSecondes); |
Ces deux m�thodes sont susceptibles de g�n�rer une exception de type java.lang.InterruptedException.
Il arrive souvent de placer des boucles infinies dans le bloc de code qui doit �tre ex�cut� par un thread. Or, si ce code ne m�nage pas un temps de pause dans la boucle, il peut accaparer � lui tout seul tout le temps CPU de la machine au d�triment des autres threads de votre application, et m�me parfois au d�triment des autres programmes qui sont en train de tourner sur votre machine. C'est pourquoi il est fortement recommand� de sp�cifier un temps de pause dans la boucle.
Code Java : | S�lectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | @Override public void run() { try { // Boucle infinie. while (true) { [...] // On met bri�vement la boucle en pause. Thread.sleep(100); } } catch (InterruptedException ex) { // Gestion de l'erreur. [...] } } |
Les applications qui g�rent des acc�s � des ressources bloquantes peuvent se reposer sur ces appels bloquants pour m�nager des temps de pause. Par exemple, un serveur peut se reposer sur l��coute d'un socket pour mettre son application en pause�; la m�thode accept() bloquera tant qu'un client ne se connecte pas au serveur, ce qui met effectivement la boucle infinie en pause�:
Code Java : | S�lectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | @Override public void run() { try (ServerSocket serverSocket = new ServerSocket(port)) { // Boucle infinie. while (true) { // Cet appel bloque jusqu'� ce qu'un client se connecte. Socket clientSocket = serverSocket.accept(); [...] } } catch (IOException ex) { // Gestion de l'erreur. [...] } } |
Les thread ayant la priorit� la plus haute sont ex�cut�s de pr�f�rence avant ceux disposant de la priorit� la plus basse. Par d�faut, un thread h�rite de la priorit� du thread dans lequel il est cr��, ce qui peut �tre g�nant quand on cr�e, par exemple, une t�che de fond pour une application graphique et qu'on d�sire que cette derni�re n'ait pas trop d'impact sur les performances du programme. Il est possible de changer cette priorit� d�ex�cution en invoquant la m�thode setPriority() du nouveau thread. La valeur pass�e en argument doit �tre contenue entre les valeurs Thread.MIN_PRIORITY et Thread.MAX_PRIORITY.
Code Java : | S�lectionner tout |
1 2 3 4 5 | // La nouvelle t�che a la m�me priorit� que le thread courant. Thread tache = [...] // Nous descendons la priorit� de cette t�che au minium. tache.setPriority(Thread.MIN_PRIORITY); tache.start(); |
Note�: le thread principal d'un programme est d�marr� avec la priorit� Thread.NORM_PRIORITY.
G�n�ralement un programme simple (ex.�: en ligne de commande) dispose d'un seul thread et donc la JVM quitte imm�diatement l'application lorsqu'elle atteint la derni�re instruction de la m�thode main(). Mais dans un environnement multi-thread, lorsque votre m�thode main() se termine, la JVM peut ne pas quitter l'application si des threads ��"normaux�� ou ��utilisateur�� sont toujours en cours d�ex�cution. En effet, la JVM quittera l'application uniquement si tous les threads ��normaux�� sont termin�s.
Ce ph�nom�ne se produit assez r�guli�rement dans environnement graphique Swing quand le programmeur oublie de configurer son JFrame pour indiquer que le programme doit se terminer lors de la fermeture de la fen�tre principale de l'application. En effet, le thread graphique et �v�nementiel EDT (Event Dispatch Thread) continue de tourner en t�che de fond, ce qui emp�che la JVM de quitter l'application.
Les threads � daemon �, quant � eux, n�emp�chent pas la fermeture de l'application.
Par d�faut, tous les threads que vous cr�ez sont des threads ��normaux�� ou ��utilisateur��, c'est-�-dire qui peuvent bloquer la fermeture de la JVM tant qu'ils s�ex�cutent. Cependant, vous pouvez les configurer en ��daemon�� (ou ��d�mon�� ou ��service��) et dans ce cas, ils ne bloqueront plus la fermeture de la JVM durant leur ex�cution. Ce genre de thread est souvent utilis� pour g�rer des t�ches de fond de basse priorit� qui tournent en parall�le au thread principal de votre application tant que cette derni�re existe. Vous pouvez transformer un thread normal en thread daemon en invoquant sa m�thode setDaemon() et en lui passant la valeur true. Cette m�thode doit �tre invoqu�e avant le d�marrage de la t�che.
Code Java : | S�lectionner tout |
1 2 3 | Thread tache = [...] tache.setDaemon(true); tache.start(); |
Le double-check locking est un idiome de programmation cens� assurer la s�curit� du patron Singleton en environnement multi-thread. Attention, ce pattern ne marche pas�!
Il peut �tre �crit comme suit�:
Code Java : | S�lectionner tout |
1 2 3 4 5 6 7 8 9 10 | public static Singleton getInstance() { if (instance==null) { synchronized (Singleton.class) { if(instance==null) { instance=new Singleton(); } } } return instance; } |
Bien qu'encore recommand�e sur le web, son utilisation est fortement d�conseill�e�!
Il existe plusieurs solutions pour s�curiser un patron Singleton dans un programme multi-thread�:
- synchroniser toute la m�thode getInstance() et payer le co�t de la synchronisation � chaque appel�;
- utiliser ThreadLocal dont l'impl�mentation n'est pas plus performante que la synchronisation�;
- abandonner la synchronisation et utiliser un initialisateur statique quand la construction du Singleton ne n�cessite pas de param�tres particuliers�;
- abandonner la synchronisation et utiliser un enum quand la construction du Singleton ne n�cessite pas de param�tre particulier.
-
Tutoriel : Le Singleton en environnement Multithread par Christophe Jollivet ;
-
Tutoriel : Patterns d'impl�mentation avec les enums Java par Laurent Claisse.
Proposer une nouvelle r�ponse sur la FAQ
Ce n'est pas l'endroit pour poser des questions, allez plut�t sur le forum de la rubrique pour �aLes sources pr�sent�es sur cette page sont libres de droits et vous pouvez les utiliser � votre convenance. Par contre, la page de pr�sentation constitue une �uvre intellectuelle prot�g�e par les droits d'auteur. Copyright � 2025 Developpez Developpez LLC. Tous droits r�serv�s Developpez LLC. Aucune reproduction, m�me partielle, ne peut �tre faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'� trois ans de prison et jusqu'� 300 000 � de dommages et int�r�ts.