Le mot-clé Volatile est utilisé pour modifier la valeur d'une variable par différents threads. Il est également utilisé pour rendre les classes thread-safe. Cela signifie que plusieurs threads peuvent utiliser une méthode et une instance des classes en même temps sans aucun problème. Le mot-clé volatile peut être utilisé avec un type primitif ou des objets.
que sont les sélecteurs en CSS
Le mot clé volatile ne met pas en cache la valeur de la variable et lit toujours la variable depuis la mémoire principale. Le mot clé volatile ne peut pas être utilisé avec des classes ou des méthodes. Cependant, il est utilisé avec des variables. Il garantit également la visibilité et la commande. Cela empêche le compilateur de réorganiser le code.
Le contenu du registre de périphérique particulier peut changer à tout moment, vous avez donc besoin du mot-clé volatile pour garantir que ces accès ne sont pas optimisés par le compilateur.
Exemple
class Test { static int var=5; }
Dans l’exemple ci-dessus, supposons que deux threads travaillent sur la même classe. Les deux threads s'exécutent sur des processeurs différents où chaque thread possède sa copie locale de var. Si un thread modifie sa valeur, le changement ne sera pas reflété dans celui d'origine dans la mémoire principale. Cela conduit à une incohérence des données car l'autre thread n'est pas conscient de la valeur modifiée.
class Test { static volatile int var =5; }
Dans l'exemple ci-dessus, les variables statiques sont des membres de classe partagés entre tous les objets. Il n'y a qu'une seule copie dans la mémoire principale. La valeur d'une variable volatile ne sera jamais stockée dans le cache. Toutes les lectures et écritures seront effectuées depuis et vers la mémoire principale.
Quand l'utiliser ?
- Vous pouvez utiliser une variable volatile si vous souhaitez lire et écrire automatiquement des variables longues et doubles.
- Il peut être utilisé comme moyen alternatif de réaliser une synchronisation en Java.
- Tous les threads de lecture verront la valeur mise à jour de la variable volatile après avoir terminé l'opération d'écriture. Si vous n'utilisez pas le mot-clé volatile, différents threads de lecture peuvent voir des valeurs différentes.
- Il est utilisé pour informer le compilateur que plusieurs threads accéderont à une instruction particulière. Cela empêche le compilateur d’effectuer une réorganisation ou une optimisation.
- Si vous n'utilisez pas le compilateur de variables volatiles, vous pouvez réorganiser le code, libre d'écrire dans la valeur du cache de la variable volatile au lieu de lire à partir de la mémoire principale.
Les points importants
- Vous pouvez utiliser le mot clé volatile avec des variables. L'utilisation d'un mot-clé volatile avec des classes et des méthodes est illégale.
- Il garantit que la valeur de la variable volatile sera toujours lue depuis la mémoire principale, et non depuis le cache de thread local.
- Si vous avez déclaré la variable comme volatile, les lectures et écritures sont atomiques
- Cela réduit le risque d’erreur de cohérence de la mémoire.
- Toute écriture dans une variable volatile en Java établit un événement avant la relation avec des lectures successives de cette même variable.
- Les variables volatiles sont toujours visibles par les autres threads.
- La variable volatile qui est une référence d'objet peut être nulle.
- Lorsqu'une variable n'est pas partagée entre plusieurs threads, vous n'avez pas besoin d'utiliser le mot clé volatile avec cette variable.
Différence entre synchronisation et mot clé volatile
Le mot-clé volatile ne remplace pas le mot-clé synchronisé, mais il peut être utilisé comme alternative dans certains cas. Il existe les différences suivantes :
mon flixeur
Mot clé volatile | Mot-clé de synchronisation |
---|---|
Le mot clé volatile est un modificateur de champ. | Le mot-clé synchronisé modifie les blocs de code et les méthodes. |
Le thread ne peut pas être bloqué en attente en cas de volatilité. | Les threads peuvent être bloqués en attente en cas de synchronisation. |
Cela améliore les performances des threads. | Les méthodes synchronisées dégradent les performances des threads. |
Il synchronise la valeur d'une variable à la fois entre la mémoire du thread et la mémoire principale. | Il synchronise la valeur de toutes les variables entre la mémoire du thread et la mémoire principale. |
Les champs volatils ne sont pas soumis à l'optimisation du compilateur. | La synchronisation est soumise à l'optimisation du compilateur. |
Exemple de mot clé volatile
Dans l'exemple suivant, nous avons défini une classe qui augmente la valeur du compteur. La méthode run () dans VolatileThread.java obtient la valeur mise à jour et l'ancienne valeur lorsque le thread commence l'exécution. Dans la classe principale, nous définissons le tableau de threads.
Données volatiles.java
public class VolatileData { private volatile int counter = 0; public int getCounter() { return counter; } public void increaseCounter() { ++counter; //increases the value of counter by 1 } }
VolatileThread.java
0,0625 en fraction
VolatileThread.java public class VolatileThread extends Thread { private final VolatileData data; public VolatileThread(VolatileData data) { this.data = data; } @Override public void run() { int oldValue = data.getCounter(); System.out.println('[Thread ' + Thread.currentThread().getId() + ']: Old value = ' + oldValue); data.increaseCounter(); int newValue = data.getCounter(); System.out.println('[Thread ' + Thread.currentThread().getId() + ']: New value = ' + newValue); } }
VolatileMain.java
public class VolatileMain { private final static int noOfThreads = 2; public static void main(String[] args) throws InterruptedException { VolatileData volatileData = new VolatileData(); //object of VolatileData class Thread[] threads = new Thread[noOfThreads]; //creating Thread array for(int i = 0; i <noofthreads; ++i) threads[i]="new" volatilethread(volatiledata); for(int i="0;" < noofthreads; threads[i].start(); starts all reader threads threads[i].join(); wait for } pre> <p> <strong>Output:</strong> </p> <pre> [Thread 9]: Old value = 0 [Thread 9]: New value = 1 [Thread 10]: Old value = 1 [Thread 10]: New value = 2 </pre> <hr></noofthreads;>