Cet article étudie principalement des exemples de code connexes de la technologie de communication de synchronisation des threads traditionnels de la concurrence de Java, comme suit.
Regardons d'abord une question:
Il y a deux fils. Le thread enfant s'exécute 10 fois d'abord, puis le thread principal s'exécute 5 fois, puis passe au thread enfant exécute 10, puis le thread principal s'exécute 5 fois ... Ce voyage aller-retour est 50 fois.
Après avoir lu cette question, il est évident que la communication entre les fils est utilisée. Permettez-moi d'analyser l'idée d'abord: d'abord il doit y avoir deux threads, puis il doit y avoir 50 boucles dans chaque thread, car chaque thread doit effectuer des tâches 50 fois aller-retour, la tâche du thread principal est d'exécuter 5 fois et la tâche du thread de l'enfant est d'exécuter 10 fois. La technologie de communication inter-thread utilise principalement wait() et notify() . La méthode Wait () fait attendre le fil actuel et libérer le verrouillage. notify() indique qu'un seul thread en attente de ce moniteur d'objet est éveillé. Complétons ce problème de communication inter-thread étape par étape.
Tout d'abord, quelle que soit la communication entre le thread principal et le thread enfant, écrivez les tâches à exécuter par chaque fil:
classe publique TraditionalThreadCommunication {public static void main (String [] args) {// Ouvrir un fil d'enfant nouveau thread (new Runnable () {@Override public void run () {for (int i = 1; i <= 50; i ++) {synchronisé (traditionnelhreadcommunication.class) {// {System.out.println ("Séquence sous-thread de" + j + ", boucle de" + i);}}}}}}). Start (); // la méthode principale est le thread principal pour (int i = 1; i <= 50; i ++) {synchronisé (traditionnel {System.out.println ("séquence de threads principaux de" + j + ", boucle de" + i);}}}}}}}}}}}}}}}}}}}Comme mentionné ci-dessus, les deux threads ont chacun 50 grandes boucles et exécutent 50 tâches, la tâche du thread de l'enfant est exécutée 10 fois et la tâche du thread principal est exécutée 5 fois. Afin d'assurer la synchronisation entre deux threads, des blocs de code de synchronisation synchronisés sont utilisés et le même verrou est utilisé: objet bytecode de la classe. Cela garantit la sécurité des fils. Mais cette conception n'est pas très bonne. Tout comme j'ai écrit dans l'impasse dans la section précédente, nous pouvons mettre des tâches de fil dans une classe. Le modèle de cette conception est plus structuré, et mettre différentes tâches de thread dans la même classe résoudra facilement le problème de synchronisation car il est facile d'utiliser le même verrou dans une classe. Modifiez donc le programme ci-dessus:
classe publique TraditionalThreadCommunication {public static void main (String [] args) {Business Business = new Business (); // New A Thread Task Processing Class // Ouvrir un fil d'enfant nouveau thread (new Runnable () {@Override public void run () {for (int i = 1; i <= 50; i ++) {busSinsiness.sub (i);}}}). Thread for (int i = 1; i <= 50; i ++) {bussinsiness.main (i);}}} // Les données courantes (y compris les verrous de synchronisation) ou plusieurs méthodes courantes à utiliser doivent être classées dans la même classe. Cette conception reflète simplement la robustesse du programme de clustering de haut niveau. Classe Business {public synchronisé void sub (int i) {for (int j = 1; j <= 10; j ++) {System.out.println ("Sub Thread Sequence de" + j + ", boucle de" + i);}} public synchronisé void main (int i) {for (int j = 1; j <= 5; j ++) {System.out.print (" J + ", boucle de" + i);}} Après cette modification, la structure du programme devient plus claire et plus robuste. Ajoutez simplement le mot clé synchronisé aux deux méthodes de tâche de thread et utilisez ce verrouillage. Mais il n'y a pas encore de communication entre les deux fils. Le résultat de l'exécution est que le thread principal déborde la tâche 50 fois et que le thread de l'enfant déborde la tâche 50 fois. La raison est très simple, car il y a une synchronisation synchronisée.
Ce qui suit continue d'améliorer le programme pour permettre la communication entre les deux threads comme décrit dans la question:
classe publique TraditionalThreadCommunication {public static void main (String [] args) {Business Business = new Business (); // New A Thread Task Processing Class // Ouvrir un fil d'enfant nouveau thread (new Runnable () {@Override public void run () {for (int i = 1; i <= 50; i ++) {busSinsiness.sub (i);}}}). Thread for (int i = 1; i <= 50; i ++) {bussinsiness.main (i);}}} // pour utiliser des données courantes (y compris les verrous de synchronisation) ou plusieurs méthodes courantes doivent être classées dans la même classe. Cette conception reflète simplement la robustesse du drame Gao Lei et du programme. Class Business {private boolean bSouldSub = true; public synchronisé void sub (int i) {while (! bSouldSub) {// Si ce n'est pas votre tour d'exécuter, essayez {this.wait (); // l'objet qui appelle la méthode wait () doit être le même que l'objet de verrouillage synchronisé. Ici, synchronisée est sur la méthode, alors utilisez ce} catch (InterruptedException e) {// TODO GÉNÉRÉ AUTO GÉNÉRÉ BLOCKE.PRINTSTACKTRACE ();}} pour (int j = 1; j <= 10; j ++) {System.out.println ("sous-thread séquence de" + j + ", Loop of" + i);} bshould this.notify (); // réveiller le thread principal en attente} public synchronisé void main (int i) {while (bSouldSub) {// si ce n'est pas votre tour d'exécuter, essayez {this.wait ();} catch (interruptedException e) {// toDo auto-généré Blocke.printStackTrace ();}} ++) {System.out.println ("Séquence de threads principaux de" + j + ", boucle de" + i);} bSouldSub = true; // change la balise this.notify (); // réveiller le thread enfant en attente}}Tout d'abord, ne parlons pas de l'implémentation spécifique du programme, d'un point de vue structurel, nous avons déjà réalisé les avantages de cette conception: il n'est pas nécessaire de modifier quoi que ce soit dans la fonction principale, et la logique sur la synchronisation inter-thread et la communication inter-thread est tout dans la classe commerciale. Différents threads de la fonction principale doivent seulement appeler les tâches correspondantes placées dans la classe. Il reflète les avantages d'un afflux élevé.
Regardons à nouveau le code spécifique. Tout d'abord, définissez une variable booléenne pour identifier quel thread doit être exécuté. Quand ce n'est pas le fil d'enfant, il dormira. Ensuite, il exécutera naturellement le fil principal. Après l'exécution, il modifiera le BSouldSub et réveillera le thread enfant. À l'heure actuelle, le fil d'enfant jugera que sans être satisfait et ne dormira pas. Il exécutera la tâche du thread enfant. De même, après que le thread principal a simplement modifié le BSoulSub, lorsque la deuxième boucle est utilisée pour exécuter la tâche du thread principal, il dormira et attendra que le fil d'enfant se réveille. Cela rend la logique très claire. Le fil principal et le fil d'enfant à tour de rôle pour exécuter leurs tâches respectives, et ce rythme est 50 fois au total.
Il y a une autre petite explication: il est en fait possible d'utiliser si pour juger, mais pourquoi utiliser? Parce que parfois les fils se réveillent Fakely (c'est comme un somnambulisme, qui dort évidemment mais se lève). S'il utilise si, après s'être réveillé, il ne reviendra pas à juger si, puis il exécutera naturellement la tâche. D'accord, un autre thread s'exécute, et cela affectera un autre thread dans un flash. Mais si c'est un moment, ce sera différent. Même si le fil est faussement éveillé, il jugera toujours pendant. Cependant, l'autre thread s'exécute pour le moment. BSouldsub n'a pas été modifié, il entre toujours pendant et dort à nouveau ~ donc il est très sûr et n'affectera pas l'autre fil! Cela se fait également dans le document JDK officiel.
Résumons la communication entre les threads.
Ce qui précède est toute l'explication détaillée du Code de technologie de communication de synchronisation de threads traditionnelle de la concurrence de Java, et j'espère que cela sera utile à tout le monde. Les amis intéressés peuvent continuer à se référer à d'autres sujets connexes sur ce site. S'il y a des lacunes, veuillez laisser un message pour le signaler. Merci vos amis pour votre soutien pour ce site!