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:
- Le fil acquiert le verrou sur le moniteur pour objet de cette .
- 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 .
- 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).
- (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.)
- 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