Table des matières
1. Observez le phénomène à travers le programme
2. Pourquoi ce phénomène se produit-il (modèle JMM) ?
dans la mémoire de travail du thread 1 n'a pas changé, donc le thread 1 a été dans une boucle infinie
Maison Java javaDidacticiel Exemple d'analyse du modèle de mémoire volatile et multithread JMM de la programmation simultanée Java

Exemple d'analyse du modèle de mémoire volatile et multithread JMM de la programmation simultanée Java

May 27, 2023 am 08:58 AM
java volatile jmm

1. Observez le phénomène à travers le programme

Avant de commencer à vous expliquer le modèle de cache multithread Java, examinons d'abord le morceau de code suivant. La logique de ce code est très simple : le thread principal démarre deux sous-threads, un thread 1 et un thread 2. Le thread 1 s'exécute en premier et le thread 2 s'exécute après avoir dormi pendant 2 secondes. Les deux threads utilisent une variable partagée shareFlag, avec une valeur initiale false. Si shareFlag est toujours égal à false, le thread 1 sera toujours dans une boucle infinie, nous définissons donc shareFlag sur true dans le thread 2.

public class VolatileTest {
  public static boolean shareFlag = false;
  public static void main(String[] args) throws InterruptedException {
    new Thread(() -> {
      System.out.print("开始执行线程1 =>");
      while (!shareFlag){  //shareFlag = false则一直死循环
        //System.out.println("shareFlag=" + shareFlag);
      }
      System.out.print("线程1执行完成 =>");
    }).start();
    Thread.sleep(2000);
    new Thread(() -> {
      System.out.print("开始执行线程2 =>");
      shareFlag = true;
      System.out.print("线程2执行完成 =>");
    }).start();
  }
}
Copier après la connexion

Si vous n'avez pas appris le modèle de thread JMM, peut-être qu'après avoir lu le code ci-dessus, vous espérez que le résultat de sortie sera le suivant :

Démarrer l'exécution du thread 1 => Démarrer l'exécution du thread 2 => Exécution du thread 2 terminée = > Exécution du thread 1 terminée =>

Comme le montre la figure ci-dessous, les gens normaux comprennent ce code. Tout d'abord, le thread 1 est exécuté pour entrer dans la boucle, le thread 2 modifie shareFlag=true et le thread 1 sort de la boucle. Par conséquent, le thread 1 qui sort de la boucle imprimera "Exécution du thread 1 terminée =>", mais après l'expérience de l'auteur, ** "Exécution du thread 1 terminée =>" ne sera pas imprimé et le thread 1 ne sortira pas de la boucle. la boucle infinie**.

Exemple danalyse du modèle de mémoire volatile et multithread JMM de la programmation simultanée Java

2. Pourquoi ce phénomène se produit-il (modèle JMM) ?

Pour expliquer les problèmes mentionnés ci-dessus, nous devons apprendre le modèle de mémoire Java JMM (Java Memory Model). Je pense qu'il est plus précis de l'appeler modèle de mémoire multithread Java.

Exemple danalyse du modèle de mémoire volatile et multithread JMM de la programmation simultanée Java

  • Tout d'abord, dans JMM, chaque thread a sa propre mémoire de travail Lorsque le programme démarre, le thread charge (lecture et chargement) les variables partagées dans sa propre mémoire de travail, charge dans la mémoire de travail du thread Variables de mémoire. sont des copies de variables partagées dans la mémoire principale. C'est-à-dire qu'il y a trois copies de shareFlag en mémoire à ce moment-là, et leurs valeurs sont toutes égales à false.

  • Lorsque le thread 2 exécute shareFlag=true, il modifie sa copie de mémoire de travail en shareFlag=true et réécrit simultanément la valeur de la copie (store&write) dans dans la mémoire principale. shareFlag=true的时候将其工作内存副本修改为shareFlag=true,同时将副本的值同步写回(store&write)到主内存中。

  • 但是线程1的工作内存中的shareFlag=false

  • Mais le
shareFlag=false

dans la mémoire de travail du thread 1 n'a pas changé, donc le thread 1 a été dans une boucle infinie

.

3. Protocole de cohérence du cache MESI

La modification des variables partagées par le thread 2 ne sera pas perçue par le thread 1, ce qui est cohérent avec les résultats expérimentaux ci-dessus et le modèle JMM. Alors, comment le thread 1 peut-il percevoir que la valeur de la variable partagée a changé ? En fait, c'est très simple. Ajoutez simplement le mot-clé volatile à la variable partagée shareFlag.
    public volatile static boolean shareFlag = false;
    Copier après la connexion
  1. Le principe sous-jacent est le suivant. L'ajout du mot-clé volatile incite JMM à suivre le protocole de cohérence du cache MESI, qui contient les spécifications d'utilisation du cache suivantes (

    Si vous ne comprenez pas, vous pouvez l'ignorer. Il sera décrit dans langage simple et exemples ci-dessous. Un instant ).

  2. Modified : Indique que les données de la ligne Cache actuelle sont modifiées (Dirty), et ne sont modifiées que dans le cache du CPU actuel à ce moment, les données de la ligne Cache sont différentes des données ; dans d'autres caches, elles sont également différentes des données en mémoire pour cette ligne.

  3. Exclusif : indique que les données dans la ligne de cache actuelle sont des données valides, et qu'il n'y a pas de ligne de données de ce type dans le cache des autres processeurs et que les données de la ligne de cache actuelle sont les mêmes que les données en mémoire ; .

  4. Partagé : Cela signifie que cette ligne de données sera mise en cache dans le cache de plusieurs processeurs, et les données dans le cache sont cohérentes avec les données dans la mémoire

  5. InvalidExemple danalyse du modèle de mémoire volatile et multithread JMM de la programmation simultanée Java : Cela signifie que les données de la ligne de cache actuelle ne sont pas valides ;

    • Les spécifications d'utilisation du cache ci-dessus peuvent être trop compliquées, pour le dire simplement,
    • Lorsque le thread 2 modifie shareFlag (voir Modifier), informez-en le. bus que j'ai modifié la variable partagée shareFlag,
    • Thread 1 surveille le Bus Lorsqu'il apprend que la variable partagée shareFlag a été modifiée, il supprimera la copie de shareFlag dans sa mémoire de travail pour la rendre invalide.
    🎜🎜Lorsque le thread 1 doit utiliser à nouveau shareFlag et constate qu'il n'y a pas de copie de la variable shareFlag dans la mémoire de travail, il se rechargera (lera et chargera) à partir de la mémoire principale🎜🎜🎜

    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!

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

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

AI Hentai Generator

AI Hentai Generator

Générez AI Hentai gratuitement.

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

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

Nombre parfait en Java Nombre parfait en Java Aug 30, 2024 pm 04:28 PM

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.

Weka en Java Weka en Java Aug 30, 2024 pm 04:28 PM

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.

Numéro de Smith en Java Numéro de Smith en Java Aug 30, 2024 pm 04:28 PM

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.

Questions d'entretien chez Java Spring Questions d'entretien chez Java Spring Aug 30, 2024 pm 04:29 PM

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.

Break or Return of Java 8 Stream Forach? Break or Return of Java 8 Stream Forach? Feb 07, 2025 pm 12:09 PM

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

Horodatage à ce jour en Java Horodatage à ce jour en Java Aug 30, 2024 pm 04:28 PM

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.

Programme Java pour trouver le volume de la capsule Programme Java pour trouver le volume de la capsule Feb 07, 2025 am 11:37 AM

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

Créer l'avenir : programmation Java pour les débutants absolus Créer l'avenir : programmation Java pour les débutants absolus Oct 13, 2024 pm 01:32 PM

Java est un langage de programmation populaire qui peut être appris aussi bien par les développeurs débutants que par les développeurs expérimentés. Ce didacticiel commence par les concepts de base et progresse vers des sujets avancés. Après avoir installé le kit de développement Java, vous pouvez vous entraîner à la programmation en créant un simple programme « Hello, World ! ». Une fois que vous avez compris le code, utilisez l'invite de commande pour compiler et exécuter le programme, et « Hello, World ! » s'affichera sur la console. L'apprentissage de Java commence votre parcours de programmation et, à mesure que votre maîtrise s'approfondit, vous pouvez créer des applications plus complexes.

See all articles