Est-il correct de dire que cela static
signifie une copie de la valeur pour tous les objets et volatile
signifie une copie de la valeur pour tous les threads?
Quoi qu'il en soit, une static
valeur variable va également être une valeur pour tous les threads, alors pourquoi devrions-nous y aller volatile
?
Réponses:
La déclaration d'une variable statique en Java signifie qu'il n'y aura qu'une seule copie, quel que soit le nombre d'objets de la classe créés. La variable sera accessible même sans aucune
Objects
création. Cependant, les threads peuvent en avoir des valeurs mises en cache localement.Lorsqu'une variable est volatile et non statique , il y aura une variable pour chacune
Object
. Donc, en surface, il ne semble pas y avoir de différence par rapport à une variable normale mais totalement différente de statique . Cependant, même avec desObject
champs, un thread peut mettre en cache une valeur variable localement.Cela signifie que si deux threads mettent à jour une variable du même objet simultanément et que la variable n'est pas déclarée volatile, il peut y avoir un cas dans lequel l'un des threads a en cache une ancienne valeur.
Même si vous accédez à une valeur statique via plusieurs threads, chaque thread peut avoir sa copie en cache locale! Pour éviter cela, vous pouvez déclarer la variable comme volatile statique et cela forcera le thread à lire chaque fois la valeur globale.
Cependant, volatile ne remplace pas une bonne synchronisation!
Par exemple:
L'exécution
concurrentMethodWrong
simultanée de plusieurs fois peut conduire à une valeur finale de compteur différente de zéro!Pour résoudre le problème, vous devez implémenter un verrou:
Ou utilisez la
AtomicInteger
classe.la source
Différence entre statique et volatile:
Variable statique : si deux threads (supposons
t1
ett2
) accèdent au même objet et mettent à jour une variable qui est déclarée comme statique, cela signifiet1
ett2
peuvent créer leur propre copie locale du même objet (y compris les variables statiques) dans leur cache respectif, alors mettez à jour faite part1
la variable statique dans son cache local ne se reflétera pas dans la variable statique dut2
cache.Les variables statiques sont utilisées dans le contexte d'Object où la mise à jour effectuée par un objet se refléterait dans tous les autres objets de la même classe mais pas dans le contexte de Thread où la mise à jour d'un thread vers la variable statique reflètera les changements immédiatement à tous les threads (dans leur cache local).
Variable volatile : si deux threads (supposons
t1
ett2
) accèdent au même objet et mettent à jour une variable qui est déclarée volatile, cela signifiet1
ett2
peuvent créer leur propre cache local de l'objet, sauf la variable qui est déclarée volatile . Ainsi, la variable volatile n'aura qu'une seule copie principale qui sera mise à jour par différents threads et la mise à jour effectuée par un thread sur la variable volatile se reflétera immédiatement sur l'autre thread.la source
volatile
variable peut être partagée entre des caches de processeur distincts. Cela ne pose aucun problème car le cache négocie la propriété exclusive de la ligne de cache avant de la modifier.En plus d'autres réponses, je voudrais ajouter une image pour elle (la photo est facile à comprendre)
static
les variables peuvent être mises en cache pour des threads individuels. Dans un environnement multithread si un thread modifie ses données en cache, cela peut ne pas refléter pour les autres threads car ils en ont une copie .volatile
garantit que les threads ne mettront pas en cache les données et utilise uniquement la copie partagée .source d'image
la source
Je pense
static
etvolatile
n'ai aucune relation du tout. Je vous suggère de lire le tutoriel java pour comprendre l'accès atomique , et pourquoi utiliser l'accès atomique, comprendre ce qui est entrelacé , vous trouverez la réponse.la source
En termes simples,
statique : les
static
variables sont associées à la classe , plutôt qu'à n'importe quel objet . Chaque instance de la classe partage une variable de classe, qui se trouve dans un emplacement fixe en mémoirevolatile : ce mot-clé s'applique aux variables de classe et d' instance .
Jetez un oeil à cet article par
Javin Paul
comprendre les variables volatiles d'une manière mieux.En l'absence de
volatile
mot-clé, la valeur de la variable dans la pile de chaque thread peut être différente. En créant la variable asvolatile
, tous les threads obtiendront la même valeur dans leur mémoire de travail et les erreurs de cohérence de la mémoire ont été évitées.Ici, le terme
variable
peut être unestatic
variable (classe) ou une variableinstance
(objet).Concernant votre requête:
Si j'ai besoin de
instance
variable dans mon application, je ne peux pas utiliser destatic
variable. Même en cas destatic
variable, la cohérence n'est pas garantie en raison du cache de thread comme indiqué dans le diagramme.L'utilisation de
volatile
variables 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 pour les autres threads.L'utilisation d'un accès aux variables atomiques simple est plus efficace que l'accès à ces variables via un code synchronisé
Certaines classes du
java.util.concurrent
package fournissent des méthodes atomiques qui ne dépendent pas de la synchronisation.Reportez-vous à cet article de contrôle de concurrence de haut niveau pour plus de détails.
Jetez un œil aux variables atomiques .
Questions SE connexes:
Volatile contre atomique
Volatile booléen vs AtomicBoolean
Différence entre volatile et synchronisé en Java
la source
volatile
plus tôt, mais cette réponse clarifie beaucoup pour moi pourquoi dois-je encore utiliservolatile
avec lastatic
variable.l'accès aux valeurs variables volatiles se fera directement depuis la mémoire principale. Il ne doit être utilisé que dans un environnement multithread. la variable statique sera chargée une fois. Si elle est utilisée dans un environnement à thread unique, même si la copie de la variable sera mise à jour et qu'il n'y aura aucun mal à y accéder car il n'y a qu'un seul thread.
Maintenant, si une variable statique est utilisée dans un environnement multi-threading, il y aura des problèmes si l'on attend le résultat souhaité de celle-ci. Comme chaque thread a sa propre copie, tout incrément ou décrément sur la variable statique d'un thread peut ne pas se refléter dans un autre thread.
si l'on attend les résultats souhaités de la variable statique, puis utilisez volatile avec statique dans le multi-threading, tout sera résolu.
la source
Pas sûr que les variables statiques soient mises en cache dans la mémoire locale du thread ou NON. Mais lorsque j'ai exécuté deux threads (T1, T2) accédant au même objet (obj) et lors de la mise à jour effectuée par le thread T1 en variable statique, cela s'est reflété dans T2.
la source
Si nous déclarons une variable statique, il n'y aura qu'une seule copie de la variable. Ainsi, chaque fois que différents threads accèdent à cette variable, il n'y aura qu'une seule valeur finale pour la variable (car il n'y a qu'un seul emplacement mémoire alloué pour la variable).
Si une variable est déclarée volatile, tous les threads auront leur propre copie de la variable mais la valeur est extraite de la mémoire principale. Ainsi, la valeur de la variable dans tous les threads sera la même.
Donc, dans les deux cas, le point principal est que la valeur de la variable est la même sur tous les threads.
la source