Nous savons que les opérations de définition des valeurs des variables en Java sont des opérations atomiques, à l'exception des variables de type long et double. En d'autres termes, il n'est pas nécessaire de synchroniser les opérations simples de lecture et d'écriture des valeurs des variables.
Avant JVM 1.2, l'implémentation du modèle de mémoire Java lisait toujours les variables de la mémoire principale, ce qui ne nécessitait pas d'attention particulière. Avec la maturité et l'optimisation de la JVM, l'utilisation de mots-clés volatils est devenue très importante dans les environnements multi-thread. Dans le modèle de mémoire Java actuel, les threads peuvent stocker des variables dans la mémoire locale (telles que les registres machine) au lieu de lire et d'écrire directement dans la mémoire principale. Cela peut amener un thread à modifier la valeur d'une variable dans la mémoire principale, tandis qu'un autre thread continue d'utiliser sa copie de la valeur de la variable dans le registre, provoquant une incohérence des données. Pour résoudre ce problème, il suffit de déclarer la variable comme volatile (instable) comme dans ce programme. Cela indique à la JVM que cette variable est instable et sera stockée dans la mémoire principale à chaque utilisation en lecture. En général
Par conséquent, dans un environnement multitâche, les indicateurs partagés entre les tâches doivent être modifiés avec volatile.
Chaque fois qu'un thread accède à une variable membre modifiée par Volatile, la valeur de la variable membre est forcée d'être relue depuis la mémoire partagée. De plus, lorsqu'une variable membre change, le thread est obligé de réécrire la valeur modifiée dans la mémoire partagée. De cette façon, à tout moment, deux threads différents voient toujours la même valeur d'une variable membre.
La spécification du langage Java indique : Pour une vitesse optimale, les threads sont autorisés à enregistrer des copies privées des variables membres partagées et à les comparer avec les valeurs originales des variables membres partagées uniquement lorsque le thread entre ou quitte un bloc de code synchronisé.
De cette manière, lorsque plusieurs threads interagissent avec un objet en même temps, il faut veiller à permettre aux threads d'obtenir des modifications dans les variables membres partagées en temps opportun.
Le mot clé volatile invite la VM : elle ne peut pas enregistrer une copie privée de cette variable membre, mais doit interagir directement avec la variable membre partagée.
Suggestion d'utilisation : utilisez volatile sur les variables membres accessibles par deux threads ou plus. Il n'est pas nécessaire de l'utiliser lorsque la variable à laquelle on accède est déjà dans un bloc de code synchronisé ou est une constante.
Étant donné que l'utilisation de volatile bloque l'optimisation du code nécessaire dans la VM, elle est moins efficace, ce mot-clé ne doit donc être utilisé que lorsque cela est nécessaire.
Dans l'implémentation de la machine virtuelle, les types de base tels que int et char comportent un seul mot. Et long et double occupent deux mots de longueur. Dans certaines implémentations de machines virtuelles, les deux longueurs de mots peuvent être traitées comme deux longueurs atomiques de mots uniques.
Si long et double ne sont pas modifiés avec volatile, si plusieurs threads accèdent à la variable, le résultat sera déroutant en raison de la non-atomicité globale de l'opération longue.
Par exemple : int, un thread écrit 4 et un autre écrit 5. La valeur finale doit être 4 ou 5. Et le type long peut être une valeur désordonnée.