L'analyse la plus complète de l'utilisation de la lecture de Java. Si vous n'avez pas effectué de recherches approfondies sur le mécanisme multithreading de Java, cet article peut vous aider à mieux comprendre les principes et les méthodes d'utilisation du multithreading Java.
1. Créez un fil
Il existe deux façons de créer des threads en Java: en utilisant la classe de threads et en utilisant l'interface Runnable. Lorsque vous utilisez l'interface Runnable, vous devez créer une instance de thread. Par conséquent, que vous créiez un fil à travers la classe de threads ou l'interface Runnable, vous devez établir une instance de la classe de threads ou de sa sous-classe. Constructeur de thread:
Méthode 1: Hériter de la classe de thread et écraser la méthode d'exécution
classe publique ThreadDemo1 {public static void main (String [] args) {Demo d = new Demo (); d.start (); pour (int i = 0; i <60; i ++) {System.out.println (thread.currentThread (). getName () + i); }}} classe Demo étend Thread {public void run () {for (int i = 0; i <60; i ++) {System.out.println (thread.currentThread (). getName () + i); }}}Méthode 2:
classe publique threaddemo2 {public static void main (String [] args) {Demo2 d = new Demo2 (); Thread t = nouveau thread (d); t.start (); pour (int x = 0; x <60; x ++) {System.out.println (thread.currentThread (). getName () + x); }}} classe Demo2 implémente Runnable {public void run () {for (int x = 0; x <60; x ++) {System.out.println (thread.currentThread (). getName () + x); }}}2. Le cycle de vie des fils
Tout comme les gens ont la naissance, la vieillesse, la maladie et la mort, les fils doivent également passer par quatre États différents: commencer (attendre), courir, suspendre et arrêter. Les quatre états peuvent être contrôlés par des méthodes dans la classe de threads. Ce qui suit est une méthode liée à ces quatre états de la classe de threads.
// Démarrer le fil
publicVoid start ();
publicVoid run ();
// suspendre et réveiller les fils
PublicVoid resume (); // non recommandé d'utiliser
Publicvoïd suspendre (); // non recommandé d'utiliser
Sleep PublicStaticVoid (Long Millis);
PublicStaticVoid Sleep (Long Millis, int nanos);
// terminer le fil
PublicVoid stop (); // non recommandé d'utiliser
Interrupt publicVoid ();
// Obtenez l'état de thread
publicboolean isalive ();
publicBoolean est Interrupted ();
PublicStaticBoolean Interrupted ();
// Méthode de jointure
publicVoid join () lève InterruptedException;
Une fois le thread établi, il n'exécute pas immédiatement le code dans la méthode d'exécution, mais est dans un état d'attente. Lorsque le thread est dans un état d'attente, vous pouvez utiliser la méthode de classe de thread pour définir diverses propriétés du thread, telles que la priorité du thread (setPriority), le nom de thread (setName) et le type de thread (setDaemon), etc.
Après avoir appelé la méthode de démarrage, le thread commence à exécuter le code dans la méthode d'exécution. Le fil entre dans l'état de course. Vous pouvez utiliser la méthode Isalive de la classe de threads pour déterminer si le thread est en cours d'exécution. Lorsque le thread est à l'état de course, Isalive renvoie true. Lorsque Isalive revient faux, le fil peut être dans l'état d'attente ou à l'état d'arrêt. Le code suivant démontre la commutation entre les trois états de création, d'exécution et d'arrêt des threads et publie la valeur de retour Isalive correspondante.
Une fois que le thread commencera à exécuter la méthode d'exécution, le thread ne quittera pas tant que la méthode d'exécution ne sera pas exécutée. Cependant, lors de l'exécution d'un thread, le thread peut être temporairement arrêté par deux méthodes. Ces deux méthodes sont suspendus et dorment. Après avoir suspendu le thread avec suspension, le fil peut être éveillé via la méthode du curriculum vitae. Après avoir utilisé le sommeil pour dormir, le fil ne peut être placé dans l'état prêt qu'après l'heure de réglage (une fois que le fil a dormi, le fil peut ne pas s'exécuter immédiatement, mais il entre dans l'état prêt et attend que le système planifie).
Il y a deux choses à noter lors de l'utilisation de la méthode de sommeil:
1. La méthode de sommeil a deux formulaires de surcharge. L'une des formulaires de surcharge peut non seulement être définie sur des millisecondes, mais aussi des nanosecondes (1 000 000 nanosecondes équivalent à 1 milliseconde). Cependant, les machines virtuelles Java sur la plupart des plates-formes de systèmes d'exploitation ne peuvent pas être exactes pour les nanosecondes, donc si les nanosecondes sont réglées pour le sommeil, la machine virtuelle Java rapprochera les millisecondes la plus proche de cette valeur.
2. Lorsque vous utilisez la méthode de sommeil, vous devez utiliser des lancers ou essayer {…} catch {…}. Parce que la méthode d'exécution ne peut pas utiliser les lancers, vous ne pouvez utiliser que Try {…} catch {…}. Lorsque le fil dort, le sommeil lancera une exception InterruptedException lors de l'interruption du thread à l'aide de la méthode d'interruption. La méthode de sommeil est définie comme suit:
PublicStaticVoid Sleep (Long Millis) lance InterruptedException
PublicStaticVoid Sleep (Long Millis, int nanos) lance InterruptedException
Il existe trois façons de résilier le fil.
1. Utilisez l'indicateur de sortie pour faire la sortie du thread normalement, c'est-à-dire que le thread se termine lorsque la méthode d'exécution est terminée.
2. Utilisez la méthode d'arrêt pour terminer avec force le thread (cette méthode n'est pas recommandée car l'arrêt est le même que la suspension et le curriculum vitae, et peut également avoir des résultats imprévisibles).
3. Utilisez la méthode d'interruption pour interrompre le thread.
1. Utilisez l'indicateur de sortie pour terminer le fil
Lorsque la méthode d'exécution est exécutée, le thread quittera. Mais parfois, la méthode d'exécution ne se termine jamais. Par exemple, l'utilisation de threads pour écouter les demandes du client dans les programmes serveurs ou d'autres tâches qui nécessitent un traitement de boucle. Dans ce cas, ces tâches sont généralement placées dans une boucle, comme en boucle. Si vous voulez que la boucle fonctionne pour toujours, vous pouvez utiliser While (true) {…} pour le gérer. Cependant, si vous souhaitez effectuer la sortie de boucle WHOR dans une certaine condition, le moyen le plus direct est de définir un indicateur de type booléen et de contrôler si la boucle While sort en définissant ce drapeau sur True ou False. Voici un exemple de fin d'un thread à l'aide du drapeau de sortie.
La fonction de la méthode de jointure consiste à transformer le thread d'exécution asynchrone en exécution synchrone. C'est-à-dire que lorsque la méthode de démarrage de l'instance de thread est appelée, la méthode reviendra immédiatement. Si une valeur calculée par ce thread doit être utilisée après l'appel de la méthode de démarrage, la méthode de jointure doit être utilisée. Si vous n'utilisez pas la méthode de jointure, il ne peut pas être garanti que lorsqu'une instruction derrière la méthode de démarrage est exécutée, le thread sera exécuté. Après avoir utilisé la méthode de jointure, le programme ne sera pas exécuté tant que le thread sorta. Le code suivant démontre l'utilisation de la jointure.
3. Problèmes de sécurité multithreads
Cause du problème: lorsque plusieurs instructions fonctionnent sur le même thread pour partager des données, un thread ne fait qu'une partie de plusieurs instructions, mais n'a pas encore fini de l'exécuter, et un autre thread participe à l'exécution, ce qui entraîne une erreur dans le partage de données.
Solution: pour plusieurs instructions qui partagent des données avec plusieurs opérations, un seul thread peut être exécuté. Pendant le processus d'exécution, d'autres threads ne s'exécutent pas.
Synchroniser les blocs de code:
classe publique threaddemo3 {public static void main (String [] args) {ticket t = new Ticket (); Thread t1 = nouveau thread (t, "fenêtre un"); Thread t2 = nouveau thread (t, "fenêtre deux"); Thread t3 = nouveau thread (t, "fenêtre trois"); Thread t4 = nouveau thread (t, "fenêtre quatre"); t1.start (); t2.start (); t3.start (); T4.Start (); }} Le ticket de classe implémente Runnable {private int ticket = 400; public void run () {while (true) {synchronisé (nouvel objet ()) {try {thread.sleep (1); } Catch (InterruptedException e) {// TODO Block de catch généré automatiquement e.printStackTrace (); } if (ticket <= 0) pause; System.out.println (thread.currentThread (). GetName () + "--- sell" + ticket--); }}}}Fonctions synchrones
classe publique threaddemo3 {public static void main (String [] args) {ticket t = new Ticket (); Thread t1 = nouveau thread (t, "fenêtre un"); Thread t2 = nouveau thread (t, "fenêtre deux"); Thread t3 = nouveau thread (t, "fenêtre trois"); Thread t4 = nouveau thread (t, "fenêtre quatre"); t1.start (); t2.start (); t3.start (); T4.Start (); }} Le ticket de classe implémente Runnable {private int ticket = 4000; public synchronisé void SaleTticket () {if (ticket> 0) System.out.println (thread.currentThread (). getName () + "Selled" + ticket--); } public void run () {while (true) {SaleTticket (); }}}Le verrouillage de la fonction synchrone est ce verrouillage de fonction de synchronisation statique est classe
Communication entre les fils
classe publique threaddemo3 {public static void main (String [] args) {classe de classe {nom de chaîne publique; Gender de chaîne privée; public void set (String Name, String Gender) {this.name = name; this.gender = genre; } public void get () {System.out.println (this.name + "...." + this.gender); }} Personne finale p = new Person (); nouveau thread (new Runnable () {public void run () {int x = 0; while (true) {if (x == 0) {p.set ("zhang san", "mâle");} else {p.set ("lili", "nv");} x = (x + 1)% 2;}}}). start (); nouveau thread (new Runnable () {public void run () {while (true) {p.get ();}}}). start (); }} / * Zhang san .... mâle zhang san .... mâle lili .... nvlili .... mâle zhang san .... nvlili ...Modifier le code ci-dessus
classe publique threaddemo3 {public static void main (String [] args) {classe de classe {nom de chaîne publique; Gender de chaîne privée; public void set (String Name, String Gender) {this.name = name; this.gender = genre; } public void get () {System.out.println (this.name + "...." + this.gender); }} Personne finale p = new Person (); nouveau thread (new Runnable () {public void run () {int x = 0; while (true) {synchronisé (p) {if (x == 0) {p.set ("zhang san", "mâle");} else {p.set ("lili", "nv");} x = (x + 1)% 2;}}}}}}). nouveau thread (new Runnable () {public void run () {while (true) {synchronisé (p) {p.get ();}}}}}). start (); }} / * lili .... nv lili .... nv lili .... nv lili ... San .... mâle zhang san .... mâle * /En attente de mécanisme de réveil
/ * * Mécanisme de réveil d'attente du fil * attendre et réveil doit être le même verrouillage * / classe publique ThreadDemo3 {Flags booléen statiques privés = false; public static void main (String [] args) {classe de classe {nom de chaîne publique; Gender de chaîne privée; public void set (String Name, String Gender) {this.name = name; this.gender = genre; } public void get () {System.out.println (this.name + "...." + this.gender); }} Personne finale p = new Person (); Nouveau thread (new Runnable () {public void run () {int x = 0; while (true) {synchronisé (p) {if (flags) try {p.wait ();} catch (InterruptedException e) {// too a été généré automatiquement le bloc de capture e.printStackTrace ();}; if (x == 0) {p.set ("zhang San", ""); } else {p.set ("lili", "nv");} x = (x + 1)% 2; Nouveau thread (new Runnable () {public void run () {while (true) {synchronisé (p) {if (! Flags) try {p.wait ();} catch (interruptedException e) {// todo a auto-généré un bloc de capture e.printstackTrace ();}; p.get (); Flags = false; }).commencer(); }}Mécanisme de production et de consommation
classe publique ThreadDemo4 {Flags booléens statiques privés = false; public static void main (String [] args) {classe des biens {nom de chaîne privée; int privé int num; public synchronisé void produce (nom de chaîne) {if (flags) try {wait (); } Catch (InterruptedException e) {// TODO Block de catch généré automatiquement e.printStackTrace (); } this.name = name + "Number:" + num ++; System.out.println ("produit ......" + this.name); Flags = true; notifyall (); } public synchronisé void consommation () {if (! Flags) try {wait (); } Catch (InterruptedException e) {// TODO Block de catch généré automatiquement e.printStackTrace (); } System.out.println ("consommé *****" + nom); Flags = false; notifyall (); }} marchandises finales g = news bourses (); nouveau thread (new Runnable () {public void run () {while (true) {g.produce ("product");}}}). start (); nouveau thread (new Runnable () {public void run () {while (true) {g.consume ();}}}). start (); }}Mécanisme de production et de consommation 2
classe publique ThreadDemo4 {Flags booléens statiques privés = false; public static void main (String [] args) {classe des biens {nom de chaîne privée; int privé int num; public synchronisé void produce (nom de chaîne) {while (flags) try {wait (); } Catch (InterruptedException e) {// TODO Block de catch généré automatiquement e.printStackTrace (); } this.name = name + "Number:" + num ++; System.out.println (thread.currentThread (). GetName () + "produit ..." + this.name); Flags = true; notifyall (); } public synchronisé void Consume () {while (! Flags) try {wait (); } Catch (InterruptedException e) {// TODO Block de catch généré automatiquement e.printStackTrace (); } System.out.println (thread.currentThread (). GetName () + "consommé *******" + nom); Flags = false; notifyall (); }} marchandises finales g = news bourses (); Nouveau thread (new Runnable () {public void run () {while (true) {g.produce ("product");}}}, "produce (" product ");}}}," produce ("product");}}}, "produce (" product ");}}}," product ");}}}," Product ");};};};};};};};}); }, "Consumer No. 1"). START (); New Thread (New Runnable () {public void run () {while (true) {g.consume ();}}, "Consumer No. 2"). Start (); Consommé ******* Numéro de produit: 48050 Producteur n ° 1 produit ... Numéro de produit: 48051 Consumer n ° 2 Consommé **** Numéro de marchandise: 48051Producteur n ° 2 produit ... Numéro de marchandise: 48052Consumer No. 2 Consémé *** *** Numéro de marchandise: 48052Producteur n ° 1 N ° 1. 48053 Consumer n ° 1 a été consommé ******* Numéro de matières premières: 48053 Producteur n ° 1 a été produit ... Numéro de produit: 48054 Consumer n ° 2 a été produit ******* Numéro de marchandise 48055 * /Ce qui précède est la compilation des informations multipliées Java. Nous continuerons d'ajouter des connaissances pertinentes à l'avenir. Merci pour votre soutien pour ce site Web!