Comment utiliser la méthode start et la méthode run dans le thread Java
méthode start et méthode run
La méthode $start()$ est utilisée pour démarrer un thread à ce moment, le thread est dans l'état ready (exécutable) et n'est pas en cours d'exécution une fois le $cpu. $ la tranche de temps est obtenue, commencez à exécuter la méthode $run()$. L'appel direct de la méthode $run()$ appelle uniquement une méthode dans une classe, qui est essentiellement exécutée dans le thread actuel. Par conséquent, cela ne peut être réalisé qu'en utilisant la méthode $start()$ pour appeler $run()$. Méthode véritable multithread.
Exemple de code
@Slf4j(topic = "c.Test4") public class Test4 { public static void main(String[] args) { Thread t1 = new Thread("t1"){ @Override public void run() { log.debug("running"); } }; t1.run(); } }
Le code ci-dessus est la méthode $run()$ qui est appelée directement. Vous pouvez voir dans les informations imprimées que le thread $main$ a exécuté cette méthode.
@Slf4j(topic = "c.Test4") public class Test4 { public static void main(String[] args) { Thread t1 = new Thread("t1"){ @Override public void run() { log.debug("running"); } }; t1.start(); } }
Et si vous utilisez la méthode $start()$ pour démarrer, c'est la vraie méthode $run$ exécutée par le thread $t1$.
Remarque
Il convient de noter que lorsque l'objet $Thread$ appelle la méthode $start()$, il entrera dans l'état prêt. Lorsqu'il est dans l'état prêt, la méthode $start()$ ne peut pas être appelée. , sinon il lancera une exception $IllegalThreadStateException$, comme indiqué dans le code suivant
@Slf4j(topic = "c.Test4") public class Test4 { public static void main(String[] args) { Thread t1 = new Thread("t1"){ @Override public void run() { log.debug("running"); } }; t1.start(); t1.start(); } }
Informations sur l'exception :
méthode sleep et méthode rendement
sleep
L'appel de la méthode $sleep()$ sera fait passer le thread actuel de l'état $Running$ à l'état $Time Waiting$ (bloqué)
D'autres threads peuvent utiliser la méthode $interrupt$ pour interrompre le thread en veille. À ce moment, la méthode $sleep$ le fera. throw InterruptedException
Le fil après la mise en veille peut ne pas être exécuté immédiatement
Il est recommandé d'utiliser le $sleep$ de $TimeUnit$ au lieu du $sleep$ de $Thread$ pour obtenir une meilleure lisibilité. Exemple de code
@Slf4j(topic = "c.Test5") public class Test5 { public static void main(String[] args) { Thread t1 = new Thread("t1"){ @Override public void run() { try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } } }; t1.start(); log.debug("t1 state {}", t1.getState()); //让主线程休眠500ms try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } log.debug("t1 state {}", t1.getState()); } } //17:13:21.729 [main] DEBUG c.Test5 - t1 state RUNNABLE //17:13:22.245 [main] DEBUG c.Test5 - t1 state TIMED_WAITING
Dans le code ci-dessus, le thread $t1$ est démarré en premier. À ce stade, l'état du thread d'impression doit être dans l'état $RUNNABLE$, et laisser le thread principal dormir empêche le thread principal d'exécuter l'impression en premier. , mais n'est pas encore entré dans l'état $sleep()$. Lorsque la méthode $sleep$ dans $run()$ est exécutée, le thread entre dans l'état $TIMED WAITING$
@Slf4j(topic = "c.Test6") public class Thread6 { public static void main(String[] args) throws InterruptedException { Thread t1 = new Thread("t1") { @Override public void run() { try { log.debug("enter sleep"); Thread.sleep(2000); } catch (InterruptedException e) { log.debug("wake up"); e.printStackTrace(); } } }; t1.start(); Thread.sleep(1000); log.debug("interrupt t1"); //被唤醒 t1.interrupt(); } }
Résultats de l'exécution
Dans le code ci-dessus, lorsque la méthode $start$ est démarrée, $t1$ Le thread entre en état de veille, imprime les informations d'invite et le temps de veille est de $2s$ Après avoir dormi $1s$ dans le thread $main$, il interrompt la veille du thread $t1$ et provoque l'interruption. informations et appelle la méthode $interrupt()$. À ce stade, le thread est interrompu et une exception est levée.
La classe $TimeUnit$ a ajouté une nouvelle unité dans laquelle dormir, qui est plus lisible, mais fondamentalement, il n'y a aucune différence. C'est juste une conversion d'unité
TimeUnit.SECONDS.sleep(1);//该语句作用是睡眠一秒
yield
Appeler $yield$ fera le. processus actuel Entrez l'état prêt $Runnable$ à partir de $Running$, puis planifiez et exécutez d'autres threads. L'implémentation spécifique dépend du planificateur de tâches du système d'exploitation (c'est-à-dire lorsqu'il n'y a pas d'autres tâches dans le planificateur de tâches, même s'il n'y a pas d'autres tâches dans le planificateur de tâches). si $cpu$ est abandonné, continuez à exécuter le thread) $sleep$ entrera dans l'état de blocage après l'exécution. Si le temps de veille ne se termine pas à ce moment, $cpu$ ne sera pas alloué au thread, mais $yield. $ entrera dans l'état prêt, c'est-à-dire que si aucun autre thread n'a besoin d'être exécuté, le thread se verra également attribuer une tranche de temps, ce qui constitue la plus grande différence entre $sleep$ et $yield$ Priorité du thread
Priorité du thread
. demandera au planificateur de donner la priorité à la planification du thread, mais ce n'est qu'une invite, le planificateur peut l'ignorer
Si $cpu$ est occupé, alors celui avec la priorité la plus élevée obtiendra plus de tranches de temps, mais lorsque $cpu$ l'est inactif, la priorité sera presque nulle
Application en veille - empêchez le CPU d'occuper 100%
sans Lorsque vous utilisez $cpu$ pour calculer, ne laissez pas $while(true)$ inactif et gaspillez $cpu$. temps, vous pouvez utiliser $yield$ ou $sleep$ pour confier l'utilisation de $cpu$ à d'autres programmes
while (true) { try { Thread.sleep(50); } catch (InterruptedException e) { e.printStackTrace(); } }
Oui Utilisez $wait$ ou des variables de condition pour obtenir des effets similaires
La différence est que les deux derniers nécessitent un verrouillage et les opérations de réveil correspondantes, qui conviennent généralement aux scénarios nécessitant une synchronisation
$sleep$ conviennent aux scénarios qui ne nécessitent pas de synchronisation de verrouillage
méthode de jointure
Les résultats d'impression du programme suivant :
@Slf4j(topic = "c.Test6") public class Test6 { static int r = 0; public static void main(String[] args) { test(); } private static void test() { log.debug("开始"); Thread t = new Thread("t1") { @Override public void run() { log.debug("开始"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } log.debug("结束"); r = 10; } }; t.start(); log.debug("r的值是{}", r); log.debug("结束"); } }
Étant donné que le thread principal et le thread $t1$ sont parallèles, le thread $t1$ a besoin de $1s$ pour calculer la valeur de $r$, et le thread principal imprimera la valeur de $r$ au début, donc la valeur imprimée est 0
Solution :
Ajoutez $t.join();$ après $t.start();$ c'est Can. La fonction de $join$ est d'attendre qu'un thread termine son exécution.
Du point de vue de l'appelant, si vous devez attendre le résultat avant de poursuivre l'exécution, c'est synchrone, et si vous n'avez pas besoin d'attendre le résultat renvoyé pour continuer l'exécution, c'est asynchrone.
Donc la méthode $join$ permet en fait de l'exécuter de manière synchrone
attente efficace
$join(milliseconds)$La méthode peut avoir un paramètre à passer dans le temps d'attente si le temps d'exécution du thread est plus long. que le temps d'attente, une fois le temps d'attente écoulé, il cessera d'attendre. Si le temps d'exécution du thread est inférieur au temps d'attente, l'attente se terminera une fois l'exécution du thread terminée. Le temps d'attente réglé n'expirera pas.
interrupt方法
打断$sleep, wait, join$的线程,即打断阻塞状态的线程
打断$sleep$的线程,会清空打断状态
@Slf4j(topic = "c.Test7") public class Test7 { public static void main(String[] args) throws InterruptedException { Thread t = new Thread("t1"){ @Override public void run() { log.debug("sleep..."); try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } } }; t.start(); Thread.sleep(1000); log.debug("interrupt"); t.interrupt(); log.debug("打断标记: {}", t.isInterrupted()); } }
打断正常运行的线程,不会清空打断状态
因此我们可以在线程中判断打断标记,来决定是否被打断,以及执行被打断之前的收尾工作。
@Slf4j(topic = "c.Test8") public class Test8 { public static void main(String[] args) throws InterruptedException { Thread t = new Thread("t1"){ @Override public void run() { while (true) { if (Thread.currentThread().isInterrupted()) { log.debug("线程被打断了"); break; } } } }; t.start(); Thread.sleep(1000); log.debug("interrupt"); t.interrupt(); } }
守护线程
默认情况下,$java$需要等待所有线程都运行结束,才会结束。有一种特殊的线程叫做守护线程,只要其他非守护线程运行结束了,即使守护线程的代码没有执行完毕,也会强制结束。
@Slf4j(topic = "c.Test10") public class Test10 { public static void main(String[] args) throws InterruptedException { Thread t = new Thread("t1") { @Override public void run() { while (true) { } } }; //设置线程为守护线程 t.setDaemon(true); t.start(); Thread.sleep(1000); log.debug("主线程结束"); } }
如果不把$t$设置为守护线程,则因为线程内部的死循环,导致程序不会结束运行。
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Outils d'IA chauds

Undresser.AI Undress
Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover
Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool
Images de déshabillage gratuites

Clothoff.io
Dissolvant de vêtements AI

Video Face Swap
Échangez les visages dans n'importe quelle vidéo sans effort grâce à notre outil d'échange de visage AI entièrement gratuit !

Article chaud

Outils chauds

Bloc-notes++7.3.1
Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise
Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1
Puissant environnement de développement intégré PHP

Dreamweaver CS6
Outils de développement Web visuel

SublimeText3 version Mac
Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Sujets chauds

Guide du nombre parfait en Java. Nous discutons ici de la définition, comment vérifier le nombre parfait en Java ?, des exemples d'implémentation de code.

Guide de Weka en Java. Nous discutons ici de l'introduction, de la façon d'utiliser Weka Java, du type de plate-forme et des avantages avec des exemples.

Guide du nombre de Smith en Java. Nous discutons ici de la définition, comment vérifier le numéro Smith en Java ? exemple avec implémentation de code.

Dans cet article, nous avons conservé les questions d'entretien Java Spring les plus posées avec leurs réponses détaillées. Pour que vous puissiez réussir l'interview.

Java 8 présente l'API Stream, fournissant un moyen puissant et expressif de traiter les collections de données. Cependant, une question courante lors de l'utilisation du flux est: comment se casser ou revenir d'une opération FOREAK? Les boucles traditionnelles permettent une interruption ou un retour précoce, mais la méthode Foreach de Stream ne prend pas directement en charge cette méthode. Cet article expliquera les raisons et explorera des méthodes alternatives pour la mise en œuvre de terminaison prématurée dans les systèmes de traitement de flux. Lire plus approfondie: Améliorations de l'API Java Stream Comprendre le flux Forach La méthode foreach est une opération terminale qui effectue une opération sur chaque élément du flux. Son intention de conception est

Guide de TimeStamp to Date en Java. Ici, nous discutons également de l'introduction et de la façon de convertir l'horodatage en date en Java avec des exemples.

Les capsules sont des figures géométriques tridimensionnelles, composées d'un cylindre et d'un hémisphère aux deux extrémités. Le volume de la capsule peut être calculé en ajoutant le volume du cylindre et le volume de l'hémisphère aux deux extrémités. Ce tutoriel discutera de la façon de calculer le volume d'une capsule donnée en Java en utilisant différentes méthodes. Formule de volume de capsule La formule du volume de la capsule est la suivante: Volume de capsule = volume cylindrique volume de deux hémisphères volume dans, R: Le rayon de l'hémisphère. H: La hauteur du cylindre (à l'exclusion de l'hémisphère). Exemple 1 entrer Rayon = 5 unités Hauteur = 10 unités Sortir Volume = 1570,8 unités cubes expliquer Calculer le volume à l'aide de la formule: Volume = π × r2 × h (4

PHP et Python ont chacun leurs propres avantages, et le choix doit être basé sur les exigences du projet. 1.Php convient au développement Web, avec une syntaxe simple et une efficacité d'exécution élevée. 2. Python convient à la science des données et à l'apprentissage automatique, avec une syntaxe concise et des bibliothèques riches.
