Maison > Java > javaDidacticiel > le corps du texte

Explication détaillée de la communication inter-thread dans le multithreading Java

黄舟
Libérer: 2017-09-14 10:51:42
original
2443 Les gens l'ont consulté

L'éditeur suivant vous proposera un article sur l'apprentissage de la programmation multi-thread Java (communication inter-thread). L'éditeur le trouve plutôt bon, je vais donc le partager avec vous maintenant et le donner comme référence pour tout le monde. Venez jeter un œil avec l'éditeur

1 Présentation

Les threads sont des individus indépendants dans le système d'exploitation, mais si ces individus ne le font pas. passer par un traitement spécial ne peut pas devenir un tout, et la communication entre les threads est l'une des solutions nécessaires pour devenir un tout. On peut dire qu'une fois que les threads seront autorisés à communiquer, l'interactivité entre les systèmes sera plus puissante. Tout en améliorant considérablement l'utilisation du processeur, cela permettra également aux programmeurs de contrôler et de superviser efficacement le traitement des tâches de chaque thread.

2. Mécanisme d'attente/notification

1. Mécanisme d'attente/notification : mécanisme d'attente/notification, wait provoque la pause du thread et notify fait que le thread suspendu continue de s'exécuter. Utilisons l'interaction entre un chef et un serveur pour illustrer :

(1) L'heure à laquelle le serveur récupère les plats dépend du chef, le serveur a donc un état "d'attente".

(2) Le chef place les plats sur la « table de livraison des plats », ce qui équivaut en fait à une notification. Ce n'est qu'alors que le serveur peut récupérer les plats et les remettre aux convives.

2. wait()

(1) Faire attendre le thread qui exécute actuellement le code. La méthode wait() est une méthode de la classe Object. Cette méthode est utilisée pour placer le thread actuel dans la « file d'attente de pré-exécution » et arrêter l'exécution à la ligne de code où se trouve wait() jusqu'à ce qu'une notification soit reçue ou. interrompu.

(2) Avant d'appeler la méthode wait(), le thread doit obtenir le verrou au niveau de l'objet de l'objet, c'est-à-dire que la méthode wait() ne peut être appelée que dans une méthode synchronisée ou un bloc synchronisé, sinon, une exception IllegalMonitorStateException sera levée. (Appartient à une sous-classe de Runtime et ne nécessite pas d'instruction try-catch pour intercepter les exceptions)

(3) Après avoir appelé la méthode wait(), le thread actuel libère le verrou et cet objet entrera dans le pool de threads en attente. En attente d'être réveillé. Avant de revenir de wait(), le thread entre en compétition avec d'autres threads en attente pour récupérer le verrou.

(4) La méthode wait() peut être interrompue par une interruption et lancer InterruptedException.

(5) wait(long) : La fonction de la méthode wait(long) avec un paramètre est d'attendre qu'un thread réveille le verrou dans un certain laps de temps. Si ce délai est dépassé, il se réveillera automatiquement.

3. notify()

(1) est utilisé pour avertir les autres threads qui peuvent attendre le verrouillage de l'objet. S'il y a plusieurs threads en attente, le planificateur de threads sélectionne au hasard l'un des threads en état d'attente, lui envoie une notification et le fait attendre pour acquérir le verrou d'objet de l'objet. (Remarque ! Ce qui est dit ici est Waiting, c'est-à-dire qu'après avoir exécuté la méthode notify(), le thread actuel ne libérera pas immédiatement le verrou de l'objet, c'est-à-dire que le thread dans l'état wait() le fera n'obtient pas le verrou de l'objet immédiatement. Le verrou doit être libéré après l'exécution du code dans le bloc de code synchronisé ! )

(2) doit également être appelé dans une méthode synchronisée ou un bloc synchronisé, c'est-à-dire le le thread doit également obtenir le niveau d'objet de l'objet avant d'appeler. lock, sinon IllegalMonitorStateException sera lancé

(3) Lorsque notify() émet une notification mais qu'il n'y a pas de thread wait() en attente, il l'aura. aucun effet.

4. notifyAll()

(1) peut faire en sorte que tous "tous" les threads de la file d'attente attendent la même ressource partagée (c'est-à-dire le même verrou ) commencez par Quitter l'état d'attente et entrez dans l'état exécutable.

5,

6, Fausse mort : " Fausse mort" "Le phénomène est en fait que le fil entre dans l'état d'attente WAITING. Si tous les threads entrent dans l'état WAITING, le programme n'exécutera plus aucune fonction et l'ensemble du projet sera dans un état arrêté. La raison en est la suivante : par exemple, dans le cas de plusieurs producteurs et de plusieurs consommateurs, le "producteur" peut réveiller le "producteur", et le "consommateur" peut réveiller le "consommateur", qui réveille le même genre. , ce qui fait que le thread continue à s'exécuter. Comment résoudre ce problème ? Remplacez simplement la méthode notify() par la méthode notifyAll(), c'est-à-dire réveillez simplement les méthodes hétérogènes ensemble.

7. En Java, le flux pipe (pipeStream) est un flux spécial qui peut être utilisé pour transmettre directement des données dans différents threads. Un thread envoie des données au canal de sortie et un autre thread lit les données du canal d'entrée. En utilisant des canaux, la communication entre différents threads est réalisée sans recourir à des éléments tels que des fichiers temporaires. Quatre classes sont fournies dans le JDK pour permettre la communication entre les threads, notamment les flux d'octets (PipedOutputStream, PipedInputStream) et les flux de caractères (PipedWriter, PipedReader).


public class Run {
 public static void main(String[] args) {
  try {
   WriteData writeData = new WriteData();
   ReadData readData = new ReadData();
   PipedOutputStream outputStream = new PipedOutputStream();
   PipedInputStream inputStream = new PipedInputStream();
   
   outputStream.connect(inputStream);//使两个Stream之间产生通信链接,这样才可以将数据进行输入输出

   ThreadRead threadRead = new ThreadRead(readData, inputStream);
   threadRead.start();
   Thread.sleep(1000);
   ThreadWrite threadWrite = new ThreadWrite(writeData, outputStream);
   threadWrite.start();
  } catch (IOException e) {
   e.printStackTrace();
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
 }
}
Copier après la connexion

3. >

1. Dans de nombreux cas, le thread principal crée et démarre un sous-thread. Si une grande quantité de calculs fastidieux doivent être effectués dans le sous-thread, le thread principal le fera souvent. se terminer avant la fin du sous-thread. À ce stade, si le thread principal veut attendre que le sous-thread termine son exécution avant de terminer, par exemple, le sous-thread traite une donnée et le thread principal veut obtenir la valeur dans les données, il doit utiliser la méthode join().

2. La fonction de join() est d'attendre que le thread soit détruit, provoquant le blocage indéfini du thread actuel, en attendant que le thread de join() soit détruit avant continuer à exécuter le code du thread actuel.

3. De même, la méthode join() peut être interrompue par la méthode interrompu() et lancer une InterruptedException.

4. Quelle est la différence entre rejoindre et synchronisé ?

(1) join() utilise la méthode wait() en interne pour attendre.

(2) Le mot-clé synchronisé utilise le principe du "moniteur d'objet" comme synchronisation.

5. Quelle est la différence entre join(long) et sleep(long) ?

(1) join(long) est implémenté en interne à l'aide de la méthode wait(long) Lorsque la méthode wait(long) est exécutée, le verrou du thread actuel est libéré et d'autres threads peuvent également appeler le. méthode de synchronisation dans ce fil. Autrement dit, après join(long), le thread libère le verrou et doit entrer en compétition avec d'autres threads pour les ressources de verrouillage.

(2) La méthode Thread.sleep(long) ne libère pas le verrou.

4. Utilisation de la classe ThreadLocal

1 Les valeurs variables peuvent être partagées sous forme de public. variables statiques. Tous les threads utilisent la même variable statique publique. Comment résoudre ce problème si l’on veut que chaque thread ait ses propres variables partagées ? La classe ThreadLocal résout le problème de la liaison de chaque thread à sa propre valeur. La classe ThreadLocal peut être comparée à une boîte qui stocke des données globales. La boîte peut stocker les données privées de chaque thread.

2. La classe ThreadLocal est isolée, c'est-à-dire que chaque thread peut stocker les données de son propre thread sans s'affecter mutuellement, et les données qu'il récupère sont également les données stockées par son propre thread. propre fil.

5. Utilisation de la classe InheritableThreadLocal

1. La classe InheritableThreadLocal hérite de la classe ThreadLocal, elle a donc les caractéristiques de la classe ThreadLocal, mais c'est un ThreadLocal spécial. Sa spécialité est que la valeur de la variable InheritableThreadLocal sera automatiquement transmise. à tous les threads enfants, mais les variables ThreadLocal ordinaires ne peuvent pas en outre, en remplaçant la méthode childValue dans cette classe, le thread enfant peut être utilisé comme parent. Une fonction arbitraire de la valeur du thread.

Remarques :

(1) Qu'est-ce qu'un sous-thread ?

inclus dans Thread thread = new Thread(new ThreadStart(delegate{
})); (Compréhension personnelle)

(2) Quel est le fil conducteur ?

L'interface utilisateur et la fonction principale sont le fil principal, à l'exception de "Programmes non inclus dans le fil" peut être considéré comme le fil principal . (Compréhension personnelle)

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!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal