Introduction à l'état des threads Java avec exemple - Cycle de vie d'un thread
Publié: 2019-01-11
États des threads
Le schéma suivant illustre les différents états dans lesquels un thread Java peut se trouver à tout moment de sa vie et les appels de méthode qui provoquent une transition vers un autre état. Ce diagramme n'est pas un diagramme d'état fini complet, mais plutôt un aperçu des facettes les plus intéressantes et les plus courantes de la vie d'un thread.
Vous êtes au bon endroit si vous avez l'une des questions ci-dessous :
- Cycle de vie d'un thread en Java
- Cycle de vie et états d'un thread en Java
- Comprendre les états des threads Java
Le reste de cette page traite Thread's life cycle
en termes d'état.

Nouveau fil
L'instruction suivante crée un nouveau thread mais ne le démarre pas, laissant ainsi le thread dans l'état étiqueté New Thread dans le diagramme.
1 |
Thread myThread = new MyThreadClass ( ) ; |
Lorsqu'un thread est dans l'état New Thread
, il s'agit simplement d'un objet Thread vide. Aucune ressource système n'a encore été allouée. Ainsi, lorsqu'un thread est dans cet état, vous pouvez uniquement démarrer le thread ou l'arrêter ; appeler toute autre méthode que start()
ou stop()
lorsqu'un thread est dans cet état n'a aucun sens et provoque une exception IllegalThreadStateException.
Exécutable
Considérez maintenant ces deux lignes de code :
1 2 |
Thread myThread = new MyThreadClass ( ) ; myThread . start ( ) ; |
La méthode start()
crée les ressources système nécessaires pour exécuter le thread, planifie l'exécution du thread et appelle la méthode run()
du thread. À ce stade, le thread est dans l'état "Runnable". Cet état est appelé "Runnable" plutôt que "Running" car le thread peut ne pas être en cours d'exécution lorsqu'il est dans cet état. De nombreux ordinateurs ont un seul processeur, ce qui rend impossible l'exécution de tous les threads "exécutables" en même temps.
Ainsi, le système d'exécution Java doit implémenter un schéma de planification qui partage le processeur entre tous les threads "Runnable". Cependant, dans la plupart des cas, vous pouvez considérer l'état "Runnable" comme simplement "Running". Lorsqu'un thread est en cours d'exécution - il est "Runnable" et est le thread actuel - les instructions de son run()
s'exécutent de manière séquentielle.
Non exécutable
Un thread passe à l'état Not Runnable
lorsque l'un de ces quatre événements se produit :
- quelqu'un appelle sa méthode
suspend()
- quelqu'un appelle sa méthode
sleep()
- le thread utilise sa méthode
wait()
pour attendre une variable de condition - le thread bloque sur les E/S.
Par exemple, la ligne en gras dans cet extrait de code
1 2 3 4 5 6 |
Thread myThread = new MyThreadClass ( ) ; myThread . start ( ) ; try { myThread . sleep ( 10000 ) ; } catch ( InterruptedException e ) { } |
met myThread
en veille pendant 10 secondes (10 000 millisecondes). Pendant ces 10 secondes, même si le processeur devenait disponible, myThread
ne fonctionnerait pas. Une fois les 10 secondes écoulées, myThread
redevient "Runnable" et maintenant, si le processeur devenait disponible, myThread
s'exécuterait.
Pour chacune des « entrées » dans l'état « Non exécutable » répertoriées ci-dessus, il existe une voie d'évacuation spécifique et distincte qui ramène le thread à l'état « Exécutable ». Une issue de secours ne fonctionne que pour son « entrée » correspondante. Par exemple, si un thread a été mis en veille, le nombre de millisecondes spécifié doit s'écouler avant que le thread redevienne "Runnable". L'appel de resume()
sur un thread endormi n'a aucun effet.
Ce qui suit indique la voie d'évacuation pour chaque entrée dans l'état "Non exécutable".

- Si un thread a été mis en veille, le nombre de millisecondes spécifié doit s'écouler.
- Si un thread a été suspendu, quelqu'un doit appeler sa méthode
resume()
. - Si un thread attend une variable de condition, quel que soit l'objet propriétaire de la variable, il doit l'abandonner en appelant
notify()
ounotifyAll()
. - Si un thread est bloqué sur les E/S, la commande d'E/S spécifiée doit se terminer.

Mort
Un thread peut mourir de deux manières : soit de causes naturelles, soit en étant tué (arrêté). Un thread meurt naturellement lorsque sa méthode run()
se termine normalement. Par exemple, la boucle while
de cette méthode est une boucle finie - elle itérera 100 fois puis se terminera.
1 2 3 4 5 6 7 |
public void run ( ) { int i = 0 ; while ( i < 100 ) { i ++ ; System . out . println ( "i = " + i ) ; } } |
Un thread avec cette méthode run()
mourra naturellement après la boucle et la méthode run()
termine.
Vous pouvez également tuer un thread à tout moment en appelant sa méthode stop()
. Cet extrait de code.
1 2 3 4 5 6 7 |
Thread myThread = new MyThreadClass ( ) ; myThread . start ( ) ; try { Thread . currentThread ( ) . sleep ( 10000 ) ; } catch ( InterruptedException e ) { } myThread . stop ( ) ; |
crée et démarre myThread
puis met le thread en cours en veille pendant 10 secondes. Lorsque le thread actuel se réveille, la ligne en gras dans le segment de code tue myThread
.
La méthode stop()
lance un objet ThreadDeath sur le thread pour le tuer. Ainsi, lorsqu'un thread est tué de cette manière, il meurt de manière asynchrone. Le thread mourra lorsqu'il recevra l'exception ThreadDeath.
IllegalThreadStateExceptionIllegalThreadStateException
Le système d'exécution lève une exception IllegalThreadStateException lorsque vous appelez une méthode sur un thread et que l'état de ce thread n'autorise pas cet appel de méthode. Par exemple, IllegalThreadStateException est levée lorsque vous appelez suspend()
sur un thread qui n'est pas "Runnable".
Comme indiqué dans les différents exemples de threads jusqu'à présent dans cette leçon, lorsque vous appelez une méthode de thread qui peut lever une exception, vous devez soit intercepter et gérer l'exception, soit déclarer que la méthode appelante lève l'exception non interceptée.
La méthode isAlive()
Et un dernier mot sur l'état des threads : l'interface de programmation de la classe Thread inclut une méthode appelée isAlive()
. isAlive()
renvoie true si le thread a été démarré et non arrêté. Ainsi, si la méthode isAlive()
renvoie false , vous savez que le thread est soit un "New Thread" ou "Dead".
Si la méthode isAlive()
renvoie true , vous savez que le thread est soit "Runnable" soit "Not Runnable". Vous ne pouvez pas faire la différence entre un « nouveau fil » et un fil « mort » ; vous ne pouvez pas non plus faire la différence entre un thread "exécutable" et un thread "non exécutable".
En regardant des exemples de threads complexes, j'ai trouvé ce très bon tutoriel sur le net. Tout le monde devrait lire ceci attentivement.