1. Concepts de base des fils
Compréhension du thread: le thread est un chemin d'exécution différent dans un programme
Chaque branche est appelée thread, et Main () est appelé la branche principale, également appelée fil principal.
Un processus n'est qu'un concept statique, un fichier .class sur la machine, un fichier .exe sur la machine, c'est ce qu'on appelle un processus. Le processus d'exécution du programme est comme ceci: premièrement, placez le code du programme dans la zone de code de la mémoire. Une fois le code placé dans la zone de code, il ne commence pas à s'exécuter immédiatement. Cependant, cela signifie qu'un processus est prêt à commencer. Le processus a été généré, mais n'a pas encore commencé à s'exécuter. C'est le processus, donc le processus est en fait un concept statique et ne peut pas être déplacé seul. L'exécution de processus habituelle fait référence au thread principal du processus qui commence à s'exécuter, c'est-à-dire que la méthode principale () commence à s'exécuter. Les processus sont un concept statique et en fait des threads s'exécutent dans nos machines.
Le système d'exploitation Windows prend en charge le multi-threading. Il peut exécuter de nombreux threads en même temps et prend également en charge plusieurs processus. Par conséquent, le système d'exploitation Windows est un système d'exploitation qui prend en charge le multi-threading et le multi-traitement. Linux et Uinux sont également des systèmes d'exploitation qui prennent en charge le multi-threading et le multi-traitement. DOS ne prend pas en charge le multi-threading et le multi-traitement. Il ne prend en charge que des processus uniques. Un seul processus s'exécute en même temps, ce qui est appelé un seul lancement.
Le CPU est-il vraiment puissant et capable d'exécuter autant de programmes en même temps? Non, l'exécution du CPU est la suivante: le CPU est très rapide, et il peut être compté des centaines de millions de fois en une seconde, donc le CPU divise son temps en petites tranches de temps. J'exécute cette tranche de temps pendant un certain temps, la prochaine fois, Slice l'exécutera pendant un certain temps, et la prochaine fois, Slice en exécutera d'autres pendant un certain temps. Bien qu'il y ait des dizaines de fils, ils peuvent les exécuter tous en très peu de temps. Mais pour nous, les humains, la vitesse d'exécution du CPU est trop rapide, il semble donc qu'il s'exécute en même temps, mais en fait, à un moment donné, il n'y a qu'un seul fil fonctionnant sur le CPU.
Tout d'abord, vous devez comprendre trois concepts lors de l'apprentissage des fils :
1. Processus: le processus est un concept statique
2. Thread: Il y a un thread principal dans un processus appelé MAIN () Méthode, qui est un programme et un chemin d'exécution différent dans un processus.
3. En même temps, un CPU ne peut prendre en charge qu'un seul thread à exécuter. Parce que le CPU fonctionne très rapidement, nous semblons que nous sommes multithreading.
Qu'est-ce que le vrai multithreading? Si votre machine a deux CPU ou deux cœurs, il est en effet multi-thread.
2. Création et démarrage des fils
Dans Java, les threads Java sont implémentés via la classe java.lang.thread, et chaque objet de thread représente un nouveau thread. Il existe deux façons de créer un nouveau thread: le premier consiste à hériter de la classe de threads, et l'autre consiste à implémenter l'interface exécutable. Lorsque la machine virtuelle commence, il y aura un fil défini par la méthode principale (public static void main ()), et ce fil est appelé le thread principal. De nouveaux threads peuvent être créés en créant des instances de thread. Vous avez juste besoin de nouveau un objet de thread et un nouveau fil apparaîtra. Chaque thread termine son fonctionnement via la méthode run () correspondant à un objet de thread spécifique. La méthode run () est appelée le corps du fil.
Exemple 1: Créez et démarrez un nouveau thread à l'aide de l'implémentation de l'interface Runnable
Créez un nouveau fil pour appeler la méthode Run
package cn.galc.test; classe publique TestThread1 {public static void main (String args []) {Runner1 r1 = new Runner1 (); // Le nouvel objet de la classe de thread sort // r1.run (); // Ceci s'appelle un appel de méthode. L'exécution de l'appel de la méthode est d'attendre que la méthode run () soit exécutée avant que la méthode principale () continue d'être exécutée. Thread t = nouveau thread (r1); // Pour démarrer un nouveau thread, vous devez être utilisé // thread (Runnable Target) est utilisé ici. Le constructeur t.start (); // démarrer le thread nouvellement ouvert, le nouveau thread exécute la méthode run (), et le nouveau thread et le thread principal s'exécuteront en parallèle pour (int i = 0; i <10; i ++) {System.out.println ("MainTheod:" + i); }}} / * Définissez une classe pour implémenter l'interface Runnable. L'implémentation de l'interface Runnable signifie que cette classe est une classe de threads * / class Runner1 implémente Runnable {public void run () {for (int i = 0; i <10; i ++) {System.out.println ("Runner1:" + i); }}}Le processus d'exécution des programmes multi-thread est le suivant:
Appelez la méthode Run directement sans ouvrir un nouveau fil
Les résultats de l'opération sont les suivants:
Exemple 2: Hériter de la classe de thread et remplacer sa méthode run () pour créer et démarrer un nouveau thread
package cn.galc.test; / * La deuxième méthode de création de threads et de démarrage: définissez une sous-classe de thread et implémentez la méthode run () * / classe publique TestThread2 {public static void main (String args []) {Runner2 r2 = new Runner2 (); r2.start (); // Appelez la méthode start () pour démarrer le thread nouvellement ouvert pour (int i = 0; i <= 10; i ++) {System.out.println ("MainMethod:" + i); }}} / * La classe Runner2 hérite de la classe de threads en instanciant un objet de classe Runner2, vous pouvez ouvrir un nouveau thread. Appelez la méthode start () héritée de la classe de threads. Vous pouvez démarrer le thread nouvellement ouvert * / class Runner2 étend Thread {public void run () {// réécriture de l'implémentation de la méthode run () pour (int i = 0; i <= 10; i ++) {System.out.println ("Runner2:" + i); }}}Le choix d'utiliser deux méthodes pour créer de nouveaux threads, à savoir l'implémentation de l'interface Runnable et l'héritage de la classe de threads devrait être prioritaire pour ouvrir un nouveau thread. Étant donné que l'implémentation d'une interface peut implémenter plusieurs, l'héritage d'une classe ne peut être qu'un seul héritage. Par conséquent, lorsque vous pouvez utiliser l'interface Runnable lors de l'ouverture d'un nouveau thread, essayez de ne pas utiliser l'héritage de la classe de threads pour ouvrir de nouveaux threads.
3. Transition de l'état du thread
3.1. Méthodes de base de contrôle du thread
3.2. Introduction à la méthode du sommeil / jointure / rendement
Exemple d'application de la méthode du sommeil:
package cn.galc.test; import java.util. *; public class testThread3 {public static void main (String args []) {mythread thread = new mythread (); thread.start (); // Appelez la méthode start () pour démarrer le fil nouvellement ouvert essayez {/*Thread.Sleep(10000); La méthode sleep () est une méthode statique déclarée dans la classe de fil, vous pouvez donc utiliser le format de thread.sleep () pour appeler * / /*mythread.sleep(10000); La classe Mythread hérite de la classe de threads et hérite naturellement de la méthode sleep (), vous pouvez donc également l'appeler en utilisant le format de mythread.sleep () * / / * L'appel des méthodes statiques peut être directement appelé sous la forme de "Nom de la classe. System.out.println ("Le fil principal dort pendant 10 secondes et recommence"); // Lorsque vous appelez la méthode statique d'une autre classe dans la méthode Main (), vous devez utiliser le nom de la méthode "class.static où la méthode statique est localisée" pour appeler / * donc voici pour permettre au thread principal de dormir pendant 10 secondes. Quel thread appelle la méthode Sleep (), alors maintenant le fil principal dort. * /} catch (InterruptedException e) {e.printStackTrace (); } //thread.interrupt () ;//USE Interrupt () Méthode pour mettre fin à l'exécution d'un thread thread.flag = false; // modifie les conditions de boucle et terminez la boucle morte / ** * Lorsqu'une interruption de l'interruption se produit, définissez directement la condition de boucle en false pour quitter la boucle morte, * puis termine l'exécution du fil de l'enfant. C'est une meilleure façon de mettre fin au fil d'enfant * / / ** * L'interruption d'appel pour briser le fil de course équivaut à verser un pot d'eau froide sur le fil principal et à briser le sous-thread exécutant. Une fois le sous-thread exécuté interrompu, une interruption de l'interruption sera lancée, ce qui exécutera l'instruction de retour et mettra fin à l'exécution du thread. So the sub-thread here ends the execution of the thread after 10 seconds of execution*/ }}class MyThread extends Thread { boolean flag = true;// Define a tag to control the conditions of the loop public void run() { /* * Note: Here, you cannot write throw Exception directly behind the run() method to throw exceptions, * Because now we need to rewrite the run() method inherited from the Thread class, the rewrite method cannot throw Exceptions différentes de la méthode réécrite. * Alors ici, vous ne pouvez écrire que essayer ... Catch () pour attraper des exceptions * / while (drapeau) { System.out.println("======================================================================================================== =======================================================================. =======================================================================. =======================================================================. =======================================================================. =======================================================================. ========================================================================. Bien sûr, il n'est pas faux de l'appeler en utilisant le format de "Nom de la classe. Nom de la méthode" * / // MyThread.Sleep (1000); // Utilisez le format de "Nom de la classe. Nom de la méthode" pour appeler la méthode statique Sleep (1000); // Si elle est interrompue pendant le sommeil, et ensuite recommencer le thread, puis le thread est à nouveau ouverte. Chaque seconde dans une boucle morte, et le temps du système actuel est imprimé chaque seconde} Catch (InterruptedException e) {/ * * En dormant, une plaque d'eau froide peut interrompre le sommeil *, lorsque le thread en cours d'exécution est interrompu par des raisons non spécialisées, une exception qui est interrompue (interrompueRésultats en cours:
Exemple de méthode de jointure:
package cn.galc.test; public class TestThread4 {public static void main (String args []) {mythread2 thread2 = new myThread2 ("mythread"); // Lors de la création d'un nouvel objet de thread, nommez l'objet de thread MyThread Thread2.Start (); // Démarrer le thread essayez {Thread2.join (); // Appelez la méthode join () pour fusionner le thread, fusionnez le thread de l'enfant Mythread dans le thread principal // Après avoir fusionné le thread, le processus d'exécution du programme est équivalent au processus d'exécution de la méthode} catch (interruptException } pour (int i = 0; i <= 5; i ++) {System.out.println ("Je suis le thread principal"); }}} class MyThread2 étend Thread {myThread2 (String S) {super (s); / * * Utilisez le mot-clé Super pour appeler le constructeur de la classe parent * L'un des constructeurs du thread de classe parent: "Thread public (nom de chaîne)" * via un tel constructeur, le thread nouvellement ouvert peut être nommé, qui facilite la gestion des threads * /} public void run () {pour (int i = 1; i <= 5; i ++) {System.out.out.Trulln ("I // use // public final string getName () défini dans le thread de classe parent, renvoie le nom de ce thread. essayez {sleep (1000); // faire dormir le fil d'enfant pendant 1 seconde à chaque fois qu'il est exécuté} catch (InterruptedException e) {return; }}}}Résultats en cours:
Exemple d'utilisation de la méthode de rendement:
package cn.galc.test; public class TestThread5 {public static void main (String args []) {mythread3 t1 = new mythread3 ("t1"); / * Deux fils d'enfants T1 et T2 ont été ouverts en même temps. T1 et T2 exécutent tous les deux la méthode run () * / / * Il y a un total de 3 threads en parallèle lors de l'exécution de ce programme, à savoir les threads enfants T1 et T2 et le thread principal * / mythread3 t2 = new mythread3 ("t2"); t1.start (); // thread de starter Child Thread T1 t2.start (); // thread enfant de démarreur T2 pour (int i = 0; i <= 5; i ++) {System.out.println ("I Am Main Thread"); }}} class MyThread3 étend Thread {myThread3 (String S) {super (s); } public void run () {for (int i = 1; i <= 5; i ++) {System.out.println (getName () + ":" + i); Si (i% 2 == 0) {rendement (); // lorsque l'exécution atteint, je peux être divisé par 2, l'exécution de thread actuel est distribuée et laisser un autre thread exécutant la méthode run () être exécuté d'abord / * * Vous pouvez voir pendant l'exécution du programme, * Lorsque le thread T1 est exécuté (I% 2 == 0) fois, il donnera le thread et permettra le thread T2 exécuté en premier *, et lorsque le fil est exécuté (EXIGHT-IL) fois, il donnera le thread au thread T1 à l'exécution prioritaire * /}}}Les résultats de l'opération sont les suivants:
Ce qui précède est tout le contenu de cet article. Nous espérons que cela pourra vous aider.