Le mot-clé volatil joue un rôle relativement important dans le multi-lancement Java. La fonction principale de la volatile est de garder les variables visibles dans le multi-threading et est le mécanisme de synchronisation le plus léger fourni en Java.
Visibilité
Toutes les variables dans le modèle de mémoire de Java (les variables ici sont des variables globales, pas des variables locales. Il n'y a pas de problème de filetage dans la méthode, car les variables sont détruites comme la méthode est appelée) sont stockés dans la mémoire principale. Chaque fil a sa propre mémoire de travail. Chaque fois que le thread s'exécute, une copie de la variable sera obtenue à partir de la mémoire principale et le fonctionnement de la variable sera effectué dans la mémoire de travail du thread. Différents threads ne peuvent pas partager la mémoire de travail et ne peuvent lire que la copie de la variable à partir de la mémoire principale. Plus précisément, il peut être exprimé dans la figure ci-dessous:
Cependant, pour volatile (en utilisant des modifications synchronisées / finales, la règle ci-dessus est rompue, c'est-à-dire que lorsque le thread modifie la valeur de la variable, d'autres threads peuvent immédiatement connaître le changement de la variable. Cependant, pour les variables ordinaires, lorsqu'un thread modifie une variable, il est nécessaire d'écrire la variable à la mémoire principale. Peut être déduit que tant qu'une variable modifiée par volatile est utilisée, il est garanti que la variable est sûre de fonctionner dans un environnement multi-thread, car il est visible pour la mémoire de travail de tous les threads, c'est-à-dire cohérent.
Test de classe publique {privé statique volatile t = 0; private static int ajout () {return t ++; } public static void testVolatile () {for (int i = 0; i <20; i ++) {thread thread = new Thread (() -> {for (int j = 0; j <1000; j ++) {add ();}}); thread.start (); } while (thread.activeCount ()> 1) {thread.yield (); } System.out.println (t); } public static void main (String [] args) {testVolatile (); }}Il est prévu que la valeur t soit de 20 000, mais il y aura une situation où la valeur t est inférieure à 20 000. Vous devriez deviner la raison. Le problème réside dans T ++. T ++ n'est pas une opération atomique. En Java, l'opération T ++ signifie d'abord pour obtenir la valeur t, puis ajouter 1, puis affecter t. Lors de l'obtention de la valeur t, il est modifié par volatile, de sorte que la dernière valeur du thread peut être obtenue. Cependant, lors de l'ajout de 1, il ne peut pas être garanti. Il est possible que d'autres threads aient déjà ajouté 1.
Alors, quel scénario est le plus adapté à utiliser volatile?
* En fonctionnement variable ne dépend pas de la valeur actuelle
* Les variables n'ont pas besoin de participer à des contraintes invariantes avec d'autres variables d'état
Traduit en chinois signifie que pour les variables qui ont à la fois lu et écrire en plusieurs threads, vous pouvez utiliser volatile pour les modifier. De cette façon, vous ne devez pas utiliser les opérations de verrouillage / synchronisées pour les opérations de lecture. La lecture directement est dû au fait que les variables sont visibles.