89 votes

Quand utilisez-vous exactement le mot clé volatile en Java?

J'ai lu " Quand utiliser 'volatile' en Java? " Mais je suis toujours confus. Comment savoir quand je devrais marquer une variable volatile? Que se passe-t-il si je me trompe, soit en omettant une valeur volatile sur quelque chose qui en a besoin, soit en mettant une valeur volatile sur quelque chose qui n'en a pas? Quelles sont les règles à suivre pour déterminer quelles variables doivent être volatiles dans du code multithread?

112voto

Enno Shioji Points 12298

En gros, vous l'utiliser lorsque vous voulez laisser un membre de la variable soit accessible par plusieurs threads, mais n'ont pas besoin composé atomicité (pas sûr si c'est la bonne terminologie).

class BadExample {
    private volatile int counter;

    public void hit(){
        /* This operation is in fact two operations:
         * 1) int tmp = this.counter;
         * 2) this.counter = tmp + 1;
         * and is thus broken (counter becomes fewer
         * than the accurate amount).
         */
        counter++;
    }
}

le ci-dessus est un mauvais exemple, parce que vous devez composé de l'atomicité.

 class BadExampleFixed {
    private int counter;

    public synchronized void hit(){
        /*
         * Only one thread performs action (1), (2) at a time
         * "atomically", in the sense that other threads can not 
         * observe the intermediate state between (1) and (2).
         * Therefore, the counter will be accurate.
         */
        counter++;
    }
}

Maintenant un exemple:

 class GoodExample {
    private static volatile int temperature;

    //Called by some other thread than main
    public static void todaysTemperature(int temp){
        // This operation is a single operation, so you 
        // do not need compound atomicity
        temperature = temp;
    }

    public static void main(String[] args) throws Exception{
        while(true){
           Thread.sleep(2000);
           System.out.println("Today's temperature is "+temperature);
        }
    }
}

Maintenant, pourquoi ne pouvez-vous pas simplement utiliser private static int temperature? En fait, vous pouvez (dans le sens que votre programme ne sera pas sauter ou quelque chose), mais le changement d' temperature par l'autre thread peut ou ne peut pas être "visible" pour le thread principal.

Fondamentalement, cela signifie qu'il est même possible que votre application. continue a écrire Today's temperature is 0 toujours si vous n'avez pas utiliser volatile (dans la pratique, la valeur tend à devenir finalement visible. Cependant, vous ne devez pas risquer de ne pas utiliser volatile lorsque cela est nécessaire, car elle peut conduire à de méchants bugs (causés par la entièrement construit des objets, etc.).

Si vous mettez de l' volatile mot clé sur quelque chose qui n'a pas besoin d' volatile, cela n'affectera pas votre code de justesse (c'est à dire le comportement ne changera pas). En termes de performances, il dépendra de la JVM. En théorie, vous pourriez obtenir une petite dégradation des performances, car le compilateur ne peut pas faire la réorganisation des optimisations ont pour invalider le cache du PROCESSEUR, etc., mais là encore, le compilateur pourrait prouver que votre domaine ne peut jamais être accédé par plusieurs threads et supprimer l'effet de l' volatile mot-clé complètement et de le compiler les mêmes instructions.

EDIT:
Répondre à ce commentaire:

Ok, mais pourquoi ne pouvons-nous pas faire todaysTemperature de synchronisation et de créer en parallèle, un getter pour la température?

Vous pouvez et il va se comporter correctement. Tout ce que vous pouvez avec volatile peut être fait avec synchronized, mais pas vice-versa. Il y a deux raisons pour lesquelles vous pourriez préférer volatile si vous le pouvez:

  1. Moins de bug source d'erreurs: Cela dépend du contexte, mais dans de nombreux cas, l'aide d' volatile est moins sujettes à la simultanéité des bugs, comme le blocage tout en maintenant le verrou, les blocages, etc.
  2. Plus performant: Dans la plupart des JVM implémentations, volatile peut avoir considérablement d'un débit plus élevé et un meilleur temps de réponse. Cependant, dans la plupart des applications, la différence est trop petite à la matière.

14voto

mdma Points 33973

Volatile qui est le plus utile dans les algorithmes sans verrouillage. Vous marquez la variable contenant des données partagées, alors que la volatilité lorsque vous n'êtes pas en utilisant le verrouillage d'accès à cette variable et que vous voulez les modifications apportées par un thread pour être visible dans un autre, ou vous souhaitez créer un "arrive-après" rapport pour s'assurer que le calcul n'est pas re-commandé, encore une fois, pour s'assurer que les changements deviennent visibles au moment opportun.

Le JMM livre de cuisine décrit les opérations qui peuvent être re-commandé et qui ne le peuvent pas.

6voto

Johannes Wachter Points 1664

Les volatile peuvent également être utilisés pour publier en toute sécurité des objets immuables dans un environnement multithread.

La déclaration d'un champ tel que public volatile ImmutableObject foo garantit que tous les threads voient toujours la référence d'instance actuellement disponible.

Voir Concurrence Java en pratique pour plus d'informations à ce sujet.

2voto

Molske Points 1596

http://mindprod.com/jgloss/volatile.html

"Le mot clé volatile est utilisé sur des variables pouvant être modifiées simultanément par d'autres threads."

"Etant donné que les autres threads ne peuvent pas voir les variables locales, il n’est jamais nécessaire de marquer les variables locales comme volatiles. Vous avez besoin de synchroniser pour coordonner les modifications apportées aux variables de différents threads, mais souvent volatile est suffisant pour les examiner."

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X