6 états et méthodes associées du thread Java

image.png

Description détaillée de l'état de la ligne Java

1. Initial (NEW): Un objet thread est nouvellement créé, mais la méthode start () n'a pas encore été appelée.

2. RUNNABLE: Les deux états prêt (prêt) et en cours d'exécution (en cours d'exécution) sont appelés collectivement "en cours d'exécution" dans les threads Java.

Une fois l'objet thread créé, d'autres threads (tels que le thread principal) appellent la méthode start () de l'objet. Les threads dans cet état sont dans le pool de threads exécutables, en attente d'être sélectionnés par la planification des threads. Bien que le droit d'utiliser le processeur n'ait pas encore été obtenu, il est déjà dans un état prêt (prêt). Un thread à l'état prêt devient un état en cours d'exécution après avoir obtenu une tranche de temps CPU.

3. Bloqué (BLOQUÉ): indique que le fil est bloqué dans un verrou lourd.

4. En attente (WAITING): le thread entrant dans cet état doit attendre que d'autres threads effectuent des actions spécifiques (notification ou interruption).

5. TIMED_WAITING: Cet état est différent de WAITING, il peut revenir par lui-même après un temps spécifié.

6. Termination (TERMINATED): indique que le thread a été exécuté.

Quelles sont les méthodes des threads Java

Ces méthodes décrites ci-dessous peuvent être vues en conjonction avec l'image ci-dessus. Comprenez son rôle dans les threads.

run () 与 start ()

La classe Thread est une abstraction du concept de thread en Java. Cela peut être compris comme ceci: nous créons simplement une nouvelle instance de Thread via le nouveau Threa (), et elle n'a pas encore été liée au thread réel dans le système d'exploitation . Ce n'est qu'après l'exécution de la méthode start () que le véritable thread de démarrage est réalisé.

La méthode Start () permet à un thread d'entrer dans la file d'attente prête pour attendre l'allocation du processeur et d'appeler la méthode run () implémentée une fois le processeur alloué. La méthode start () ne peut pas être appelée à plusieurs reprises et une exception sera jeté s'il est appelé à plusieurs reprises.

La méthode run est l'endroit où la logique métier est implémentée. Elle est essentiellement la même que n'importe quelle méthode membre de n'importe quelle classe. Elle peut être exécutée à plusieurs reprises ou appelée individuellement.

rendement (fil poli)

Cas de ne pas utiliser de fils polis

Image 24.png

Image 25.png

Exemples d'utilisation de fils polis

Image 26.png

Image 27.png

La méthode yield () oblige le thread actuel à abandonner la possession du processeur. Mais l'heure de la reddition ne peut pas être fixée. Les ressources de verrouillage ne seront pas non plus libérées. Remarque: tous les threads n'ont pas besoin d'un verrou, et l'emplacement où yield () est appelé ne contient pas nécessairement le verrou. Nous pouvons complètement attendre que le verrou soit libéré avant d'appeler la méthode yield.

Le but de yield () est de permettre aux threads de même priorité de tourner correctement. Cependant, en pratique, il n'y a aucune garantie que yield () atteindra le but de la concession, car le thread de concession peut être sélectionné à nouveau par l'ordonnanceur de threads.

Conclusion: yield () ne fait pas passer le thread à l'état d'attente / endormi / blocage. Dans la plupart des cas, yield () fera passer le thread de l'état en cours d'exécution à l'état prêt, mais cela peut ne pas être efficace. On peut seulement dire que la tranche de temps doit être raccourcie autant que possible pour offrir des opportunités à d'autres fils.

Rejoindre (rejoindre le fil de discussion) (voici un site de test commun)

En ajoutant le thread spécifié au thread actuel, deux threads s'exécutant en alternance peuvent être fusionnés en exécution séquentielle. Par exemple, la méthode Join du thread A est appelée dans le thread B et le thread B ne continuera pas à s'exécuter jusqu'à ce que le thread A ait terminé son exécution.

De nombreux novices comprennent toujours l'écart lorsqu'ils apprennent à rejoindre les threads.

Par exemple: dans le thread principal, préparez-vous à démarrer deux nouveaux threads. Vous voulez maintenant que ces deux threads aient un ordre de priorité, ils seront implémentés comme ceci:

image.png

Lorsque le code est en cours d'exécution, il s'avère que deux threads s'exécutent en même temps. La question était donc perplexe. En fait, vous ne comprenez peut-être pas entièrement le principe de la méthode de jointure.

Nous appelons la méthode join pour rejoindre le thread. Qui est la référence pour rejoindre? C'est vrai, l'objet de référence est le thread principal où il se trouve actuellement. Au lieu de votre fil de discussion.

image.png

Lorsque nous avons changé le code en ceci, les deux threads thread et thread2 ont un ordre de priorité. Et la raison pour laquelle il peut atteindre l'ordre entre les ready-made est: lorsque le thread est démarré, nous effectuons l'opération de jointure. A ce moment, notre fil conducteur entrera dans un état d'attente de réveil. Tant que le thread de thread n'est pas exécuté, le thread principal continue de s'exécuter. À ce moment, le thread thread2 commencera à démarrer, afin de continuer l'opération de jointure. A ce moment, le thread mian entrera également dans l'état d'attente de réveil et ne terminera pas son cycle de vie tant que thread2 ne sera pas également exécuté.

Comprendre la jointure à partir du code source

Lors de l'introduction du cas tout à l'heure, j'ai mentionné à plusieurs reprises que l'appel de la méthode de jointure amènerait le thread actuel à entrer dans l'état d'attente de réveil.

Hein? Pourquoi attend-il l'état de réveil. Pourquoi ne bloque-t-il pas?

Nous entrons le code source de la méthode de jointure.

image.png

Nous avons constaté que join (0) a été appelé dans la méthode de jointure; continuez donc à cliquer pour voir.

image.png

Bon gars, j'ai vu un synchronisé d'un coup d'œil, tu m'as dit qu'il attendait d'être réveillé?

Je suis désolé, pouvoir passer à cette étape signifie que vous avez obtenu le verrou de classe de la classe où se trouve la fonction principale.

image.png

Par conséquent, nous laissons réellement le thread entrer dans l'attente, c'est la méthode wait (long).

Hein? En entendant ce que le blogueur a dit, il comprend vraiment plus clairement le concept d'état de fil. Mais pourquoi veux-tu autant le battre? Attendez une minute, notre problème, héros, n'a pas encore été résolu.

Nous nous souvenons que lorsque nous avons appelé la méthode join, nous avons en fait appelé la méthode join (0). Le programme est donc obligé de passer à l'étape suivante.

image.png

Alors le problème est. La méthode wait est appelée ici pour mettre le thread principal en attente, mais quand se réveillera-t-il?

Après avoir longtemps cherché le programme, je n'ai tout simplement pas vu où le réveil avait été effectué. Enfin, je me suis demandé si c'était au moment de la destruction du thread, et je suis allé voir si la classe Thread avait réécrit la méthode finalize (), mais malheureusement ce n'était pas là. Et ça ne peut pas être ici. Étant donné que le thread exécutant la méthode finalize () est un thread de faible priorité, bien qu'il soit exécuté, ce temps d'attente doit être fatal dans un environnement multithread.

J'ai trouvé des informations sur Internet, et bien sûr, il y a encore plus de patrons. J'ai trouvé la réponse. Comme je n'ai pas le code source jvm pour le moment, j'ai copié les choses de ce grand dieu. Le thread est toujours exécuté, mais cette fois, c'est la couche inférieure du jvm qui fera quelques vérifications

image.png

Avant de fermer le thread, le jvm détectera le thread parent dans lequel il se trouve, que ce soit parce qu'il attend. Puis exécutez notfyAll (), pour que le parent soit réveillé.

Lorsque vous le comprendrez à ce niveau, vous le réaliserez sûrement et vous laisserez partir le blogueur.

Priorité du fil

Dans un thread Java, la priorité est contrôlée par une priorité de variable de membre entier, la plage de priorité va de 1 à 10 et la priorité peut être modifiée par la méthode setPriority (int) lorsque le thread est construit. La priorité par défaut est 5 et les threads avec une priorité plus élevée se voient allouer plus de tranches de temps que les threads avec une priorité inférieure.

Lors de la définition de la priorité des threads, vous devez définir une priorité plus élevée pour les threads fréquemment bloqués (opérations de veille ou d'E / S). Les threads qui sont plus gourmands en calculs (nécessitent plus de temps CPU ou des calculs partiels) sont définis sur une priorité inférieure pour garantir que le processeur ne sera pas monopolisé. Sur différents JVM et systèmes d'exploitation, il y aura des différences dans la planification des threads. Certains systèmes d'exploitation ignorent même le réglage de la priorité des threads.

Fil de démon

image.png

Le programme ci-dessus est sûr que le thread principal se termine plus tôt que le thread démon, jetons un coup d'œil à l'effet en cours.

image.png

Tant que l'exécution du thread principal se termine, le thread démon attaché au thread principal se termine également. Pour des raisons asynchrones, je vais courir un peu plus.

Sera finalement exécuté (accrochant l'intervieweur)

image.png

image.png

Pour résumer

Le thread de démon (démon) est un thread de support, car il est principalement utilisé pour la planification en arrière-plan et le travail de support dans le programme. Cela signifie que lorsqu'il n'y a pas de threads non-Daemon dans une machine virtuelle Java, la machine virtuelle Java se fermera. Vous pouvez définir le thread en tant que thread Daemon en appelant Thread.setDaemon (true). Nous ne l'utilisons généralement pas. Par exemple, le thread de garbage collection est le thread Daemon.

Le thread Daemon est utilisé pour terminer le travail de support, mais le bloc finally du thread Daemon n'est pas nécessairement exécuté lorsque la machine virtuelle Java se termine. Lors de la création d'un thread Daemon, vous ne pouvez pas vous fier au contenu du bloc finally pour vous assurer que la logique de fermeture ou de nettoyage des ressources est exécutée.

 

 

 

 

 

Je suppose que tu aimes

Origine blog.csdn.net/weixin_47184173/article/details/115107520
conseillé
Classement