34 votes

Mot clé volatile en Java - Clarification

Je suis vraiment confus au sujet de ce que j'ai lu sur les applications des mots clés volatils en java.

  1. L'énoncé suivant est-il correct? "une écriture dans un champ volatile se produit avant chaque lecture suivante du même champ"

  2. Idéalement, quand utiliser un mot-clé volatile?

  3. Quelle est la différence entre:

     class TestClass
    {  private int x;
    
    
       synchronized int get(){return x;}
       synchronized void set(int x){this.x = x;}
    
    
    }
     

et

 class TestClass
{  private volatile int x;

   int get(){return x;}
   void set(int x){this.x = x;}

}
 

60voto

Kerem Baydoğan Points 4814

volatile est un modificateur de champ, tandis que synchronisés modifie les blocs de code et des méthodes. Donc, nous pouvons définir trois variantes d'un simple accesseur à l'aide de ces deux mots-clés:

     int i1;
     int geti1() {return i1;}

     volatile int i2;
     int geti2() {return i2;}

     int i3;
     synchronized int geti3() {return i3;}

geti1() accède à la valeur actuellement stockés dans i1 dans le thread courant. Les Threads peuvent avoir des copies locales de variables, et les données n'ont pas à être les mêmes que les données détenues dans d'autres threads.En particulier, un autre thread peut avoir mis à jour i1 dans ce thread, mais la valeur dans le thread actuel pourrait être différente de celle mise à jour de la valeur. En fait, Java a l'idée d'un "principal" de la mémoire, et c'est la mémoire qui contient le courant de la "bonne" valeur pour les variables. Les fils peuvent avoir leur propre copie des données pour les variables, et le fil de la copie peut être différente de la "main" de la mémoire. Donc, en fait, il est possible pour le "principal" de la mémoire pour avoir une valeur de 1 pour l' i1, pour thread1 d'avoir une valeur de 2 pour i1 et pour thread2 d'avoir une valeur de 3 pour i1 si thread1 et thread2 ont à la fois mis à jour i1, mais ces mises à jour de la valeur n'a pas encore été propagées à "principale" de la mémoire ou d'autres threads.

D'autre part, geti2() efficacement accède à la valeur de i2 de "principal" de la mémoire. Un volatile variable n'est pas autorisé à avoir une copie locale d'une variable qui est différente de la valeur actuellement détenus dans des "principaux" de la mémoire. Effectivement, une variable déclarée volatile doit avoir ses données synchronisées sur tous les threads, de sorte que chaque fois que vous accéder ou de mettre à jour la variable dans n'importe quel thread, tous les autres threads de voir immédiatement la même valeur. Généralement variables ont un plus grand accès et de mise à jour de frais généraux que les "simples" variables. Généralement, les threads sont autorisés à avoir leur propre copie de données, pour une meilleure efficacité.

Il y a deux différences entre volitile et synchronisés.

Tout d'abord synchronisé obtient et libère les verrous sur les moniteurs qui peut forcer un seul thread à la fois pour exécuter un bloc de code. C'est assez bien connue aspect synchronisé. Mais synchronisé synchronise également de la mémoire. En fait synchronisée synchronise l'ensemble de fil de la mémoire avec "principal" de la mémoire. Si l'exécution d' geti3() effectue les opérations suivantes:

  1. Le fil acquiert le verrou sur le moniteur pour objet de cette .
  2. Le fil de la mémoire supprime toutes les variables, c'est à dire qu'il les a toutes ses variables efficacement la lecture de "principal" de la mémoire .
  3. Le bloc de code est exécuté (dans ce cas, le réglage de la valeur de retour de la valeur actuelle de i3, qui peuvent avoir été réinitialisé à partir de "principal" de la mémoire).
  4. (Tout changement de variables seraient normalement maintenant être rédigés à l'ordre de "principal" de la mémoire, mais pour geti3() nous n'avons pas de modifications.)
  5. Le thread libère le verrou sur le moniteur pour objet de cette.

Alors, où volatile ne synchronise que la valeur d'une variable entre le fil de la mémoire et de la "main" de la mémoire, synchronisé synchronise la valeur de toutes les variables entre le fil de la mémoire et de la "main" de la mémoire, et les écluses et les rejets d'un moniteur de démarrage. Clairement synchronisé est susceptible d'avoir plus de ressources que les volatiles.

http://javaexp.blogspot.com/2007/12/difference-between-volatile-and.html

6voto

Steve Kuo Points 15196

volatile garantit que la lecture de la variable reflète toujours la valeur la plus à jour. Le runtime peut y parvenir de différentes manières, notamment en ne mettant pas en cache ou en actualisant le cache lorsque la valeur a changé.

2voto

John Vint Points 19804

bwawok échappé, mais le mot clé volatile n'est pas seulement pour la mémoire de la visibilité. Avant de Java 1.5 a été publiée le mot clé volatile a déclaré que le champ d'obtenir la plus récente de la valeur de l'objet en appuyant sur la mémoire principale à chaque fois pour les lectures et de rinçage pour les écritures.

Aujourd'hui, le mot clé volatile syas deux choses très importantes:

  1. Ne vous inquiétez pas comment mais je sais que lors de la lecture d'un champ volatile, vous aurez toujours la plus à jour de la valeur.
  2. Un compilateur ne peut pas re commander un volatile en lecture/écriture à maintenir le programme de commande.

0voto

gawi Points 5073

D'un point de vue client, un champ volatile privé est masqué de l'interface publique tandis que les méthodes synchronisées sont plus visibles.

0voto

Alexander Pogrebnyak Points 24964

Pour répondre à la partie 3 de votre question, et, en partie, partie 2.

Il n'est pas fonctionnel différence entre synchronized et volatile des échantillons.

Cependant, chacun a ses propres inconvénients, en termes de performance. Dans certains cas volatile de la performance peut être vraiment pire qu'à l'aide de synchronized ou d'autres primitives de java.util.concurrent. Pour la discussion de ce voir -> http://stackoverflow.com/questions/989839/why-arent-variables-in-java-volatile-by-default.

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