Dans la programmation multithread Java, un volatile est souvent trouvé. Parfois, ce mot-clé est souvent confondu avec synchronisé ou verrouillage. L'analyse spécifique est la suivante:
Dans un environnement multi-thread, il y aura un problème de visibilité des variables des membres: chaque thread en Java a un espace mémoire d'une pile de threads, ce qui enregistre les informations variables du thread lors de son exécution. Lorsqu'un thread accède à une certaine valeur de variable, il trouvera d'abord la mémoire de tas de l'objet ou le contenu spécifique de la pile (type de données natif) en fonction de l'adresse de la variable, puis enregistrez la même copie de valeur dans la pile de threads de ce thread. Ensuite, toutes les opérations de cette variable n'ont rien à voir avec le contenu variable de la pile avant la sortie du thread. Il fonctionne sur la copie dans la pile de threads. Une fois l'opération terminée, le résultat de l'opération sera réécrit à la mémoire principale. S'il y a deux threads A et B, et que les collègues exploitent une certaine variable x; A ajoute 1 à x, puis la copie obtenue par B peut être le résultat de x plus 1, ou x; Pour vous assurer que la dernière variable de données en mémoire est nécessaire pour ajouter le mot clé volatil, donc chaque fois que vous fonctionnez sur X, vous vérifierez si la valeur de la variable dans la pile de thread est la même que la valeur de la variable en mémoire, et si elle est différente, elle sera à nouveau chargée.
Par exemple:
classe publique ThreadSee {// Le thread T1 effectuera des opérations correspondantes en fonction de la valeur de l'indicateur, et le thread principal modifiera la valeur de T1 public static void main (String [] args) lance InterruptedException {ThreadTest th = new ThreadTest (); Thread t1 = nouveau thread (th); t1.start (); Thread.Sleep (1000); th.changeflag (); Thread.Sleep (2000); System.out.println (th.getflag ()); }} classe Threadtest implémente Runnable {// Lorsqu'un thread accède à une variable, il le chargera dans la pile de thread correspondante. Chaque opération, elle doit obtenir les dernières données dans la mémoire Boolean StopFlag privée volatile; @Override public void run () {int i = 0; while (! stopflag) {i ++; System.out.println ("==" + thread.currentThread (). GetName ()); } System.out.println ("Finition du thread:" + i); } public void changeflag () {this.stopflag = true; System.out.println (thread.currentThread (). GetName () + "*********"); } public boolean getflag () {return stopflag; }} Si le code ci-dessus est supprimé, il continuera de s'exécuter dans une boucle morte.
Mais volatile ne peut garantir la synchronisation des filetages
Par exemple:
classe publique Threadsave implémente Runnable {static threadsave sync = new Threadsave (); Int j = 0 statique volatile statique; // Lock Lock = new ReentrantLock (); public void inscan () {// lock.lock (); pour (int i = 0; i <10000000; i ++) {j ++; } // lock.unlock (); } @Override public void run () {inscan (); } public static void main (String [] args) lève InterruptedException {thread t1 = new Thread (sync); Thread t2 = nouveau thread (sync); t1.start (); t2.start (); t1.join (); t2.join (); System.out.println (J); }} Le résultat de l'exécution selon le code ci-dessus ne devrait pas être de 20000000,
Parce que pour les variables modifiées par volatile, la machine virtuelle JVM garantit que la valeur chargée de la mémoire principale à la mémoire de travail du thread est la dernière.
Par exemple, si le thread 1 et le thread 2 effectuent des opérations de pile de threads et de lecture de mémoire principale, et constatez que la valeur du nombre dans la mémoire principale est de 5, alors la dernière valeur sera chargée. Une fois le nombre de tas du thread 1 modifié, il sera écrit dans la mémoire principale et la variable de nombre dans la mémoire principale deviendra 6;
Étant donné que Thread 2 a déjà effectué des opérations de lecture et de chargement, après avoir effectué l'opération, la valeur variable du nombre de mémoire principal sera également mise à jour à 6;
Cela provoque la concurrence après que deux threads soient modifiés avec le mot clé volatil dans le temps.
En résumé:
Volatile garantira seulement que le thread effectue une action qui vérifie si la valeur variable de la pile de thread actuelle est la même que la valeur de données dans la mémoire principale, c'est tout. Lock ou synchronisé garantira qu'un seul thread entre la méthode à un certain moment, garantissant ainsi sa sécurité de fil.
Donc, si plusieurs threads modifient une variable volatile, il n'y a pas de sens logique réel. Si un thread modifie la valeur variable des autres threads qui dépendent de la modification, il sera utile pour le moment.
Ce qui précède concerne cet article, j'espère qu'il sera utile à l'apprentissage de tout le monde.