mot-clé volatile en Java
Le mot-clé volatile
en Java est utilisé pour indiquer que la valeur d'une variable sera modifiée par différents threads. Il garantit que les modifications apportées à une variable sont toujours visibles par les autres threads, ce qui évite les problèmes de mise en cache des threads.
Utilisation
Le mot-clé volatile
est principalement utilisé dans la programmation multithread pour garantir que les mises à jour d'une variable sont propagées de manière prévisible entre les threads.
Syntax
volatile dataType variableName;
dataType
: Le type de la variable (par exemple,int
,boolean
, etc.).variableName
: Le nom de la variable.
Exemples
Exemple 1 : Utilisation de base
public class VolatileExample extends Thread {
private volatile boolean running = true;
public void run() {
while (running) {
// Thread is running
}
System.out.println("Thread stopped.");
}
public void stopRunning() {
running = false;
}
public static void main(String[] args) throws InterruptedException {
VolatileExample thread = new VolatileExample();
thread.start();
Thread.sleep(1000);
thread.stopRunning();
thread.join();
}
}
Dans cet exemple, la variable running
est marquée comme volatile
. La méthode run
vérifie la variable running
dans une boucle. La méthode stopRunning
définit running
comme false
, ce qui arrête la boucle. Le mot-clé volatile
garantit que les modifications apportées à running
sont immédiatement visibles par la méthode run
.
Exemple 2 : Volatile avec plusieurs fils
public class VolatileCounter {
private volatile int counter = 0;
public void increment() {
counter++;
}
public int getCounter() {
return counter;
}
public static void main(String[] args) throws InterruptedException {
VolatileCounter vc = new VolatileCounter();
Runnable task = () -> {
for (int i = 0; i < 1000; i++) {
vc.increment();
}
};
Thread t1 = new Thread(task);
Thread t2 = new Thread(task);
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println("Counter value: " + vc.getCounter());
}
}
Dans cet exemple, la variable counter
est marquée comme volatile
. Deux threads incrémentent simultanément la variable counter
. Le mot-clé volatile
garantit que chaque thread voit la valeur la plus récente de counter
.
Conseils et bonnes pratiques
- Garantie de visibilité: Utilisez
volatile
pour garantir la visibilité des modifications apportées aux variables entre les différents threads. Il garantit qu'une lecture d'une variable volatile renvoie toujours l'écriture la plus récente de n'importe quel thread. - Atomicité:
volatile
ne garantit pas l'atomicité. Pour les actions composées (par exemple, les opérations d'incrémentation), envisagez d'utiliser d'autres mécanismes de synchronisation tels que les blocssynchronized
ouAtomicInteger
.private AtomicInteger counter = new AtomicInteger(0); counter.incrementAndGet();
- Cas d'utilisation: Approprié pour les drapeaux, les variables d'état et d'autres variables pour lesquelles la dernière valeur est critique mais les opérations composées ne sont pas nécessaires.
- Évitez la surutilisation: Une utilisation excessive de
volatile
peut entraîner des problèmes de performance. Ne l'utilisez que lorsque cela est nécessaire pour garantir la visibilité. - Combinez avec d'autres synchronisations: Dans les scénarios complexes, combinez
volatile
avec d'autres mécanismes de synchronisation pour garantir à la fois la visibilité et l'atomicité.private volatile boolean flag = false; synchronized (this) { flag = true; }
- Cohérence de la mémoire: Le mot-clé
volatile
permet d'éviter les erreurs de cohérence de la mémoire en établissant une relation "happens-before", garantissant que les modifications apportées à une variable volatile sont visibles par les autres threads.