web-dev-qa-db-fra.com

Avez-vous déjà utilisé le mot clé volatile en Java?

Au travail aujourd'hui, je suis tombé sur le mot clé volatile en Java. Ne le connaissant pas très bien, j'ai trouvé cette explication: 

Théorie et pratique de Java: Gérer la volatilité

Étant donné le détail dans lequel cet article explique le mot clé en question, l'utilisez-vous déjà ou pouvez-vous jamais voir un cas dans lequel vous pourriez utiliser ce mot clé de manière correcte?

565
Richard

volatile a une sémantique pour la visibilité de la mémoire. Fondamentalement, la valeur d'un champ volatile devient visible pour tous les lecteurs (les autres threads en particulier) à la fin d'une opération d'écriture. Sans volatile, les lecteurs pourraient voir une valeur non mise à jour.

Pour répondre à votre question: Oui, j’utilise une variable volatile pour contrôler si du code continue une boucle. La boucle teste la valeur volatile et continue si elle est true. La condition peut être définie sur false en appelant une méthode "stop". La boucle voit false et se termine lorsqu'elle teste la valeur après l'exécution de la méthode d'arrêt.

Le livre " Java Concurrency in Practice ", que je recommande vivement, donne une bonne explication de volatile. Ce livre est écrit par la même personne que celle qui a écrit l'article d'IBM auquel il est fait référence dans la question (en fait, il cite son livre au bas de cet article). Mon utilisation de volatile est ce que son article appelle "l'indicateur d'état de modèle 1".

Si vous voulez en savoir plus sur le fonctionnement de volatile sous le capot, consultez la page le modèle de mémoire Java . Si vous voulez aller au-delà de ce niveau, consultez un bon livre d'architecture d'ordinateur tel que Hennessy & Patterson et consultez la cohérence du cache et la cohérence du cache.

670
Greg Mattes

“… Le modificateur volatile garantit que tout thread qui lit un champ verra la dernière valeur écrite.”- Josh Bloch

Si vous envisagez d’utiliser volatile, lisez le paquet Java.util.concurrent qui traite du comportement atomique.

Le message de Wikipédia sur Singleton Pattern indique l’utilisation volatile.

156
Ande TURNER

Point important à propos de volatile: 

  1. La synchronisation en Java est possible en utilisant les mots clés Java synchronized et volatile et les verrous.
  2. En Java, nous ne pouvons pas avoir la variable synchronized. L'utilisation du mot clé synchronized avec une variable est illégale et entraînera une erreur de compilation. Au lieu d’utiliser la variable synchronized en Java, vous pouvez utiliser la variable Java volatile, qui ordonnera aux threads JVM de lire la valeur de la variable volatile dans la mémoire principale et de ne pas la mettre en cache localement.
  3. Si une variable n'est pas partagée entre plusieurs threads, il n'est pas nécessaire d'utiliser le mot clé volatile.

la source

Exemple d'utilisation de volatile:

public class Singleton {
    private static volatile Singleton _instance; // volatile variable
    public static Singleton getInstance() {
        if (_instance == null) {
            synchronized (Singleton.class) {
                if (_instance == null)
                    _instance = new Singleton();
            }
        }
        return _instance;
    }
}

Nous créons instance paresseusement au moment de la première demande.

Si nous ne créons pas la variable _instancevolatile, le thread qui crée l'instance de Singleton n'est pas en mesure de communiquer avec l'autre thread. Ainsi, si le thread A crée l'instance Singleton et juste après la création, le processeur corrompt, etc., tous les autres threads ne pourront pas voir la valeur de _instance comme non nulle et ils croiront qu'elle est toujours affectée à la valeur null. 

Pourquoi cela arrive-t-il? Etant donné que les threads de lecteur ne font pas de verrouillage et tant que le thread d'écriture ne sort pas d'un bloc synchronisé, la mémoire ne sera pas synchronisée et la valeur de _instance ne sera pas mise à jour dans la mémoire principale. Avec le mot clé Volatile en Java, cela est géré par Java lui-même et ces mises à jour seront visibles par tous les fils du lecteur. 

Conclusion: Le mot clé volatile est également utilisé pour communiquer le contenu de la mémoire entre les threads. 

Exemple d'utilisation de sans volatile:

public class Singleton{    
    private static Singleton _instance;   //without volatile variable
    public static Singleton getInstance(){   
          if(_instance == null){  
              synchronized(Singleton.class){  
               if(_instance == null) _instance = new Singleton(); 
      } 
     }   
    return _instance;  
    }

Le code ci-dessus n'est pas thread-safe. Bien qu'il vérifie à nouveau la valeur de l'instance dans le bloc synchronisé (pour des raisons de performances), le compilateur JIT peut réorganiser le bytecode de manière à ce que la référence à l'instance soit définie avant que le constructeur n'ait terminé son exécution. Cela signifie que la méthode getInstance () renvoie un objet qui n'a peut-être pas été initialisé complètement. Pour rendre le code thread-safe, le mot-clé volatile peut être utilisé depuis Java 5 pour la variable d'instance. Les variables marquées comme étant volatiles ne sont visibles par les autres threads que lorsque le constructeur de l'objet a complètement terminé son exécution.
La source

 enter image description here

volatile usage in Java:

Les itérateurs de type fast-fast sont généralement mis en oeuvre à l'aide d'un compteur volatile sur l'objet liste.

  • Lorsque la liste est mise à jour, le compteur est incrémenté. 
  • Lors de la création d'une Iterator, la valeur actuelle du compteur est incorporée dans l'objet Iterator.
  • Lorsqu'une opération Iterator est effectuée, la méthode compare les deux valeurs de compteur et génère une ConcurrentModificationException si elles sont différentes.

L'implémentation d'itérateurs à sécurité intrinsèque est généralement légère. Ils s'appuient généralement sur les propriétés des structures de données de l'implémentation de liste spécifique. Il n'y a pas de schéma général. 

95
Premraj

volatile est très utile pour arrêter les threads.

Non pas que vous deviez écrire vos propres threads, Java 1.6 a beaucoup de pools de threads Nice. Mais si vous êtes sûr d'avoir besoin d'un fil, vous devez savoir comment l'arrêter.

Le motif que j'utilise pour les discussions est:

public class Foo extends Thread {
  private volatile boolean close = false;
  public void run() {
    while(!close) {
      // do work
    }
  }
  public void close() {
    close = true;
    // interrupt here if needed
  }
}

Remarquez comme il n'y a pas besoin de synchronisation

49
Pyrolistical

Un exemple courant d'utilisation de volatile consiste à utiliser une variable volatile boolean en tant qu'indicateur pour terminer un thread. Si vous avez démarré un thread et que vous souhaitez pouvoir l'interrompre en toute sécurité depuis un autre thread, vous pouvez le faire vérifier régulièrement un indicateur. Pour l'arrêter, définissez l'indicateur sur true. En rendant l'indicateur volatile, vous pouvez vous assurer que le thread qui le vérifie verra qu'il a été défini lors de sa prochaine vérification sans avoir à utiliser un bloc synchronized.

30
Dave L.

Personne n'a mentionné le traitement des opérations de lecture et d'écriture pour les types long et double variable. Les lectures et les écritures sont des opérations atomiques pour les variables de référence et pour la plupart des variables primitives, à l'exception des types de variables longues et doubles, qui doivent utiliser le mot clé volatile pour être des opérations atomiques. @lien

12
Donatello Boccaforno

Oui, volatile doit être utilisé chaque fois que vous souhaitez qu'une variable mutable soit accessible par plusieurs threads. Ce n'est pas très courant car généralement, vous devez effectuer plus d'une opération atomique unique (par exemple, vérifier l'état de la variable avant de la modifier), auquel cas vous utiliseriez plutôt un bloc synchronisé.

12
ykaganovich

Une variable déclarée avec le mot clé volatile a deux qualités principales qui la rendent spéciale.

  1. Si nous avons une variable volatile, elle ne peut pas être mise en cache dans la mémoire cache de l'ordinateur (microprocesseur) par aucun thread. L'accès a toujours eu lieu à partir de la mémoire principale.

  2. S'il y a une opérationwritesur une variable volatile et que soudain une opérationreadest demandée, il est garanti que l'opérationwrite sera terminée avant l'opération de lecture.

Deux qualités ci-dessus déduisent que

  • Tous les threads lisant une variable volatile liront définitivement la dernière valeur. Parce qu'aucune valeur en cache ne peut la polluer. De plus, la demande de lecture ne sera accordée qu'après l'achèvement de l'opération d'écriture en cours.

Et d'autre part

  • Si nous étudions plus en détail le # 2 que j'ai mentionné, nous pouvons voir que le mot clé volatile est un moyen idéal de conserver une variable partagée comportant le nombre'n' de threads lus et un seul thread d'écriturepour y accéder. Une fois que nous avons ajouté le mot clé volatile, c'est terminé. Pas d'autres frais généraux sur la sécurité des threads.

À l'inverse, 

Nousne pouvons pasutiliser uniquement le mot clé volatile pour satisfaire une variable partagée qui dispose dede plusieurs threads d'écriture y accédant.

11
Supun Wijerathne

OMI deux scénarios importants autres que l’arrêt du fil dans lequel le mot clé volatile est utilisé sont 

  1. Mécanisme de verrouillage à double contrôle . Utilisé souvent dans le design Singleton Pattern. Dans ce singleton object needs to be declared volatile.
  2. Wakeups parasites . Le fil peut parfois sortir de l'appel en attente même si aucun appel de notification n'a été émis. Ce comportement est appelé réveil suprême. Cela peut être contré en utilisant une variable conditionnelle (indicateur booléen). Placez l'appel wait () dans une boucle while tant que le drapeau est vrai. Donc, si le thread sort d'un appel en attente pour une raison autre que notify/notifyall, alors le drapeau rencontre est toujours vrai et les appels attendent donc à nouveau. Avant d'appeler notify, définissez cet indicateur sur true. Dans ce cas, le boolean flag is declared as volatile.
9
Aniket Thakur

volatile garantit uniquement que tous les threads, même eux-mêmes, sont incrémentés. Par exemple: un compteur voit le même visage de la variable en même temps. Il n'est pas utilisé à la place de choses synchronisées, atomiques ou autres, il rend complètement les lectures synchronisées. Veuillez ne pas le comparer avec d'autres mots-clés Java. Comme le montre l'exemple ci-dessous, les opérations de variables volatiles sont également atomiques: elles échouent ou réussissent d'un coup.

package io.netty.example.telnet;

import Java.util.ArrayList;
import Java.util.List;

public class Main {

    public static volatile  int a = 0;
    public static void main(String args[]) throws InterruptedException{

        List<Thread> list = new  ArrayList<Thread>();
        for(int i = 0 ; i<11 ;i++){
            list.add(new Pojo());
        }

        for (Thread thread : list) {
            thread.start();
        }

        Thread.sleep(20000);
        System.out.println(a);
    }
}
class Pojo extends Thread{
    int a = 10001;
    public void run() {
        while(a-->0){
            try {
                Thread.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            Main.a++;
            System.out.println("a = "+Main.a);
        }
    }
}

Même si vous mettez volatile ou non, les résultats seront toujours différents. Mais si vous utilisez AtomicInteger comme ci-dessous, les résultats seront toujours les mêmes. C'est pareil avec synchronisé aussi.

    package io.netty.example.telnet;

    import Java.util.ArrayList;
    import Java.util.List;
    import Java.util.concurrent.atomic.AtomicInteger;

    public class Main {

        public static volatile  AtomicInteger a = new AtomicInteger(0);
        public static void main(String args[]) throws InterruptedException{

            List<Thread> list = new  ArrayList<Thread>();
            for(int i = 0 ; i<11 ;i++){
                list.add(new Pojo());
            }

            for (Thread thread : list) {
                thread.start();
            }

            Thread.sleep(20000);
            System.out.println(a.get());

        }
    }
    class Pojo extends Thread{
        int a = 10001;
        public void run() {
            while(a-->0){
                try {
                    Thread.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                Main.a.incrementAndGet();
                System.out.println("a = "+Main.a);
            }
        }
    }
5
fatih tekin

Vous devrez utiliser un mot clé "volatile" ou "synchronisé" et tous les autres outils et techniques de contrôle de la concurrence que vous pourriez avoir à votre disposition si vous développez une application multithread. Un exemple d'une telle application est les applications de bureau.

Si vous développez une application qui serait déployée sur un serveur d'applications (Tomcat, JBoss AS, Glassfish, etc.), vous n'avez pas à gérer vous-même le contrôle de la concurrence, car il est déjà traité par le serveur d'applications. En fait, si je me souvenais bien, la norme Java EE interdisait tout contrôle de la simultanéité dans les servlets et les EJB, car il fait partie de la couche «infrastructure» dont vous êtes censé être libéré. Vous ne contrôlez la concurrence que dans une telle application si vous implémentez des objets singleton. Cela a même déjà été résolu si vous tricotez vos composants avec frameworkd, comme Spring.

Ainsi, dans la plupart des cas de développement Java où l'application est une application Web et utilisant un framework IoC tel que Spring ou EJB, vous n'avez pas besoin d'utiliser 'volatile'.

5
Rudi Adianto

Oui, je l'utilise beaucoup - cela peut être très utile pour du code multi-thread. L'article que vous avez cité est bon. Bien qu'il y ait deux choses importantes à garder à l'esprit:

  1. Vous ne devez utiliser volatil que si vous comprenez parfaitement ce qu'il fait et comment il diffère de synchronisé. Dans de nombreuses situations, volatile semble, En surface, être une alternative plus simple, plus performante que Synchronisée, alors que, souvent, une meilleure compréhension de est la seule option qui fonctionnerait.
  2. volatile ne fonctionne pas réellement dans beaucoup de machines anciennes, bien que synchronisé le fasse. Je me souviens d’avoir vu un document faisant référence aux différents niveaux de prise en charge dans différentes machines virtuelles, mais malheureusement, je ne le trouve pas pour le moment. Examinez-le à fond si vous utilisez Java pre 1.5 ou si vous n’avez pas le contrôle sur les machines virtuelles sur lesquelles votre programme sera exécuté.
4
MB.

Absolument oui. (Et pas seulement en Java, mais aussi en C #.) Il est parfois nécessaire d’obtenir ou de définir une valeur qui est garantie comme une opération atomique sur votre plate-forme donnée, un int ou un booléen, par exemple, les frais généraux de blocage de fil. Le mot clé volatile vous permet de vous assurer que lorsque vous lisez la valeur, vous obtenez la valeur current et non une valeur en cache qui vient d'être rendue obsolète par une écriture sur un autre thread.

3
dgvid

Chaque thread accédant à un champ volatile lira sa valeur actuelle avant de continuer, au lieu d'utiliser (potentiellement) une valeur en cache.

Seule la variable membre peut être volatile ou transitoire.

3
tstuber

Il existe deux utilisations différentes du mot clé volatile.

  1. Empêche la machine virtuelle Java de lire les valeurs du registre (en tant que cache) et force la lecture de sa valeur à partir de la mémoire.
  2. Réduit le risque d'erreurs de cohérence de la mémoire.

Empêche JVM de lire les valeurs dans le registre et force son valeur à lire de la mémoire.

Un indicateur busy est utilisé pour empêcher un thread de continuer pendant que le périphérique est occupé et si l'indicateur n'est pas protégé par un verrou:

while (busy) {
    /* do something else */
}

Le thread de test continuera lorsqu'un autre thread désactive l'indicateur busy:

busy = 0;

Cependant, étant donné que Occupé est fréquemment utilisé dans le processus de test, la machine virtuelle Java peut optimiser le test en plaçant la valeur Occupé dans un registre, puis tester le contenu du registre sans lire la valeur Occupé en mémoire avant chaque test. Le thread de test ne verra jamais occupé occupé et l'autre thread ne changera que la valeur de busy en mémoire, ce qui entraînera un blocage. Déclarer l'indicateur busy comme volatile force la lecture de sa valeur avant chaque test.

Réduit le risque d'erreur de cohérence de la mémoire.

L'utilisation de variables volatiles réduit le risque de erreurs de cohérence de la mémoire, car toute écriture dans une variable volatile établit une relation "se produit-avant" avec les lectures suivantes de cette même variable. Cela signifie que les modifications apportées à une variable volatile sont toujours visibles par les autres threads.

La technique de lecture, écriture sans erreurs de cohérence de mémoire est appelée action atomique.

Une action atomique est une action qui se produit effectivement en même temps. Une action atomique ne peut pas s'arrêter au milieu: elle se produit complètement ou ne se produit pas du tout. Aucun effet secondaire d'une action atomique n'est visible jusqu'à ce que l'action soit terminée.

Vous pouvez spécifier ci-dessous des actions atomiques:

  • Les lectures et les écritures sont atomiques pour les variables de référence et pour la plupart des variables primitives (Tous les types sauf les types long et double).
  • Les lectures et les écritures sont atomiques pour toutes les variables déclarées volatile (Y compris les variables longues et doubles).

À votre santé!

2
dheeran

Volatile suit.

1> La lecture et l'écriture de variables volatiles par différents threads proviennent toujours de la mémoire, et non du propre cache ou du registre du processeur du thread. Ainsi, chaque thread traite toujours avec la dernière valeur . 2> Lorsque 2 threads différents fonctionnent avec la même instance ou des variables statiques dans le segment de mémoire, les actions des autres peuvent être considérées comme étant dans le désordre. Voir le blog de jeremy manson à ce sujet. Mais volatile aide ici.

La suite du code en cours d'exécution montre comment un certain nombre de threads peuvent s'exécuter dans un ordre prédéfini et imprimer des sorties sans utiliser de mot clé synchronisé.

thread 0 prints 0
thread 1 prints 1
thread 2 prints 2
thread 3 prints 3
thread 0 prints 0
thread 1 prints 1
thread 2 prints 2
thread 3 prints 3
thread 0 prints 0
thread 1 prints 1
thread 2 prints 2
thread 3 prints 3

Pour ce faire, nous pouvons utiliser le code courant complet suivant.

public class Solution {
    static volatile int counter = 0;
    static int print = 0;
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Thread[] ths = new Thread[4];
        for (int i = 0; i < ths.length; i++) {
            ths[i] = new Thread(new MyRunnable(i, ths.length));
            ths[i].start();
        }
    }
    static class MyRunnable implements Runnable {
        final int thID;
        final int total;
        public MyRunnable(int id, int total) {
            thID = id;
            this.total = total;
        }
        @Override
        public void run() {
            // TODO Auto-generated method stub
            while (true) {
                if (thID == counter) {
                    System.out.println("thread " + thID + " prints " + print);
                    print++;
                    if (print == total)
                        print = 0;
                    counter++;
                    if (counter == total)
                        counter = 0;
                } else {
                    try {
                        Thread.sleep(30);
                    } catch (InterruptedException e) {
                        // log it
                    }
                }
            }
        }
    }
}

Le lien github suivant a un fichier readme, qui donne une explication appropriée . https://github.com/sankar4git/volatile_thread_ordering

2
sankar banerjee

Les variables volatiles sont une synchronisation légère. Lorsque la visibilité des dernières données parmi tous les threads est requise et que l'atomicité peut être compromise, dans de telles situations, les variables volatiles doivent être préférées. Les variables de lecture sur volatiles renvoient toujours les écritures les plus récentes effectuées par un thread, car elles ne sont ni mises en cache dans des registres ni dans des caches où les autres processeurs ne peuvent pas voir. Volatile est Lock-Free. J'utilise volatile, lorsque le scénario répond aux critères mentionnés ci-dessus. 

2
Neha Vari

De la documentation Oracle page , la nécessité d’une variable volatile s’impose pour résoudre les problèmes de cohérence de la mémoire:

L'utilisation de variables volatiles réduit le risque d'erreurs de cohérence de la mémoire, car toute écriture dans une variable volatile établit une relation passe-avant avec les lectures suivantes de cette même variable. 

Cela signifie que les modifications apportées à une variable volatile sont toujours visibles par les autres threads. Cela signifie également que lorsqu'un thread lit une variable volatile, il voit non seulement la dernière modification apportée à la variable volatile, mais également les effets secondaires du code qui a conduit à la modification.

Comme expliqué dans la réponse Peter Parker, en l'absence de modificateur volatile, la pile de chaque thread peut avoir sa propre copie de variable. En rendant la variable volatile, les problèmes de cohérence de la mémoire ont été résolus. 

Consultez la page jenkov tutorial pour une meilleure compréhension. 

Jetez un coup d’œil à la question SE sur le sujet pour plus de détails sur les cas d’utilisation volatile:

Différence entre volatile et synchronisé en Java

Un cas d'utilisation pratique:

Vous avez plusieurs threads, qui doivent imprimer l'heure actuelle dans un format particulier, par exemple: Java.text.SimpleDateFormat("HH-mm-ss"). Yon peut avoir une classe, qui convertit l'heure actuelle en SimpleDateFormat et met à jour la variable toutes les secondes. Tous les autres threads peuvent simplement utiliser cette variable volatile pour imprimer l'heure actuelle dans les fichiers journaux. 

1
Ravindra babu

Vous trouverez ci-dessous un code très simple pour démontrer l'exigence de volatile.

// Code to prove importance of 'volatile' when state of one thread is being mutated from another thread.
// Try running this class with and without 'volatile' for 'state' property of Task class.
public class VolatileTest {
    public static void main(String[] a) throws Exception {
        Task task = new Task();
        new Thread(task).start();

        Thread.sleep(500);
        long stoppedOn = System.nanoTime();

        task.stop(); // -----> do this to stop the thread

        System.out.println("Stopping on: " + stoppedOn);
    }
}

class Task implements Runnable {
    // Try running with and without 'volatile' here
    private volatile boolean state = true;
    private int i = 0;

    public void stop() {
        state = false;
    } 

    @Override
    public void run() {
        while(state) {
            i++;
        }
        System.out.println(i + "> Stopped on: " + System.nanoTime());
    }
}

Lorsque volatile n'est pas utilisé: vous ne verrez jamais le message 'Stopped on: xxx' même après 'Stopping on: xxx' et le programme continue de s'exécuter.

Stopping on: 1895303906650500

Lorsque volatile est utilisé: , vous verrez immédiatement le message 'Arrêté: xxx'.

Stopping on: 1895285647980000
324565439> Stopped on: 1895285648087300
0
manikanta

La clé volatile, lorsqu'elle est utilisée avec une variable, s'assurera que les threads lisant cette variable verront la même valeur. Maintenant, si vous avez plusieurs threads en lecture et en écriture sur une variable, rendre la variable volatile ne sera pas suffisant et les données seront corrompues. Les threads d'image ont lu la même valeur, mais chacun d'entre eux a fait quelques sauts (disons incrémenté d'un compteur). Lors de l'écriture dans la mémoire, l'intégrité des données est violée. C’est pourquoi il est nécessaire de synchroniser la varible (différentes manières sont possibles)

Si les modifications sont effectuées par 1 thread et que les autres doivent simplement lire cette valeur, le composant volatile sera approprié.

0
Java Main

Une variable Volatile est modifiée de manière asynchrone par l'exécution simultanée de threads dans une application Java. Il n'est pas autorisé de disposer d'une copie locale d'une variable différente de la valeur actuellement conservée dans la mémoire "principale". En effet, une donnée déclarée volatile doit avoir ses données synchronisées sur tous les threads, de sorte que chaque fois que vous accédez à la variable ou que vous la mettez à jour dans un thread, tous les autres threads voient immédiatement la même valeur. Bien sûr, il est probable que les variables volatiles ont un accès plus lourd et une surcharge de mise à jour que les variables "ordinaires", car les threads de raison peuvent avoir leur propre copie de données pour une meilleure efficacité.

Lorsqu'un champ est déclaré volatil, le compilateur et le moteur d'exécution sont avertis que cette variable est partagée et que les opérations correspondantes ne doivent pas être réorganisées avec d'autres opérations en mémoire. processeurs, de sorte qu'une lecture d'une variable volatile renvoie toujours l'écriture la plus récente par un thread.

pour référence, reportez-vous à cette http://techno-terminal.blogspot.in/2015/11/what-are-volatile-variables.html

0
satish

la variable volatile est généralement utilisée pour la mise à jour instantanée (vidage) dans la ligne principale du cache partagé une fois mise à jour, afin que les modifications soient immédiatement répercutées sur tous les threads de travail.

0
Niyaz Ahamad

J'aime l'explication de Jenkov :

Le mot clé Java volatile est utilisé pour marquer une variable Java comme "en cours de stockage dans la mémoire principale". Plus précisément, cela signifie que chaque lecture d'une variable volatile sera lue dans la mémoire principale de l'ordinateur et non dans le cache du processeur, et que toute écriture dans une variable volatile sera écrite dans la mémoire principale et pas uniquement dans le cache du processeur .

En réalité, depuis Java 5, le mot clé volatile garantit plus que cela Les variables volatiles sont écrites et lues dans la mémoire principale. 

Il s’agit d’une garantie de visibilité étendue appelée garantie sur la survenance.

Considérations de performance de volatile

La lecture et l'écriture de variables volatiles entraînent la lecture ou l'écriture de la variable dans la mémoire principale. Lire et écrire dans la mémoire principale coûte plus cher que d'accéder au cache du processeur. L'accès aux variables volatiles empêche également la réorganisation des instructions, qui est une technique d'amélioration des performances normale. Par conséquent, vous ne devez utiliser des variables volatiles que lorsque vous devez réellement renforcer la visibilité des variables.

0
yoAlex5