Volatile Vs statique en java

Est-il correct de dire que statique signifie une copie de la valeur de tous les objets volatile signifie une copie de la valeur pour tous les threads?

quoi qu'il en soit une valeur variable statique va aussi être une valeur pour tous les threads, alors pourquoi devrions-nous aller pour volatile ?

242
demandé sur leppie 2010-03-11 12:01:24

7 réponses

déclarant une variable statique en Java, signifie qu'il n'y aura qu'une seule copie, peu importe le nombre d'objets de la classe créés. La variable sera accessible même sans aucune création de Objects . Cependant, les threads peuvent avoir localement des valeurs cachées de celui-ci.

Lorsqu'une variable est volatile et non statique , il y aura une variable pour chaque Object . Donc, à la surface, il il semble qu'il n'y ait pas de différence par rapport à une variable normale mais totalement différente de statique . Cependant, même avec les champs Object , un thread peut cacher une valeur variable localement.

cela signifie que si deux threads mettent à jour simultanément une variable du même objet, et que la variable n'est pas déclarée volatile, il peut y avoir un cas dans lequel l'un des threads a dans le cache une ancienne valeur.

même si vous accédez à un statique valeur à travers plusieurs threads, chaque thread peut avoir sa copie locale! Pour éviter cela, vous pouvez déclarer la variable comme statique volatile et cela forcera le fil à lire à chaque fois la valeur globale.

Toutefois, volatile n'est pas un substitut à une bonne synchronisation!

Par exemple:

private static volatile int counter = 0;

private void concurrentMethodWrong() {
  counter = counter + 5;
  //do something
  counter = counter - 5;
}

Executing concurrentMethodWrong concurremment plusieurs fois peut conduire à une valeur finale du compteur différent de zéro!

Pour résoudre le problème, vous devez implémenter une serrure:

private static final Object counterLock = new Object();

private static volatile int counter = 0;

private void concurrentMethodRight() {
  synchronized (counterLock) {
    counter = counter + 5;
  }
  //do something
  synchronized (counterLock) {
    counter = counter - 5;
  }
}

ou utilisez la classe AtomicInteger .

331
répondu stivlo 2016-07-09 08:09:40

la Différence Entre la Statique et de la Volatilité :

Variable statique : si deux Threads (supposez t1 et t2 ) accèdent au même objet et mettent à jour une variable qui est déclarée statique, alors cela signifie t1 et t2 peuvent faire leur propre copie locale du même objet (y compris les variables statiques) dans leur cache respectif, ainsi mise à jour effectuée par t1 à la variable statique dans sa cache locale wont ne réfléchit pas dans la variable statique pour le cache t2 .

les variables statiques sont utilisées dans le context of Object où la mise à jour effectuée par un objet refléterait dans tous les autres objets de la même classe mais pas dans le contexte du 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 et t2 ) accèdent au même objet et mettent à jour une variable déclarée comme volatile, alors cela signifie t1 et t2 peuvent créer leur propre cache local de l'objet sauf la variable déclarée comme volatile . Ainsi la variable volatile n'aura qu'une seule copie principale qui sera mise à jour par différents threads et mise à jour faite par un thread vers la variable volatile la variable réfléchira immédiatement à l'autre Thread.

277
répondu Som 2015-02-25 12:51:41

en plus d'autres réponses, je voudrais ajouter une image pour elle(pic rend facile à comprendre)

enter image description here

static les variables peuvent être mises en cache pour des fils individuels. Dans l'environnement fileté multiple si un thread modifie ses données cachées, cela peut ne pas refléter pour les autres threads car ils ont une copie de celui-ci.

volatile déclaration s'assure que les threads ne cache pas les données et utilise la copie partagée seulement.

image source

21
répondu mrsrinivas 2017-08-21 08:47:29

je pense static et volatile n'ont pas de relation du tout. Je vous suggère de lire le tutoriel java pour comprendre Atomic Access , et pourquoi utiliser atomic access , comprendre ce qui est interleaved , vous trouverez réponse.

5
répondu Amitābha 2018-01-30 23:35:17

en termes simples,

  1. statique : static , les variables sont associées avec le classe , plutôt qu'avec n'importe quel objet . Chaque instance de la catégorie partage une variable de catégorie, qui est en un emplacement fixe dans la mémoire

  2. volatile : ce mot-clé est applicable à la fois classe et instance variables.

L'utilisation de variables volatiles réduit le risque d'erreurs de cohérence de la mémoire, parce que toute écriture à une variable volatile établit une relation se produit-avant les lectures subséquentes de cette même variable. Cela signifie que les changements les variables volatiles sont toujours visibles aux autres fils

regardez cet article par Javin Paul pour mieux comprendre les variables volatiles.

enter image description here

en l'absence du mot-clé volatile , la valeur de la variable dans la pile de chaque fil peut être différente. En faisant la variable comme volatile , tous les threads obtiendront la même valeur dans leur mémoire de travail et les erreurs de consistance de mémoire ont été évitées.

ici, le terme variable peut être soit static (classe) variable ou instance (objet) variable.

concernant votre requête:

de toute façon une valeur variable statique va aussi être une valeur pour tous les threads, alors pourquoi devrions-nous aller pour volatile?

si j'ai besoin instance variable dans mon application, Je ne peux pas utiliser static variable. Même dans le cas de la variable static , la cohérence n'est pas garantie en raison du cache de Thread comme indiqué dans le diagramme.

L'utilisation des variables volatile réduit le risque d'erreurs de cohérence de la mémoire, parce que toute écriture à une variable volatile établit un happens-before relationship with subsequent reads of that same variable. Cela signifie que les changements à une variable volatile sont toujours d'autres threads.

de plus, cela signifie aussi que lorsqu'un thread lit une variable volatile, il voit non seulement le dernier changement vers la variable volatile, mais aussi les effets secondaires du code qui a conduit au changement = > des erreurs de cohérence de mémoire sont encore possibles avec les variables volatiles . Pour éviter les effets secondaires, vous devez utiliser synchronisé variables. Mais il y a une meilleure solution en java.

utiliser la variable atomique simple l'accès est plus efficace que l'accès à ces variables par le biais du code synchronisé

certaines des classes du paquet java.util.concurrent fournissent des méthodes atomiques qui ne reposent pas sur la synchronisation.

se Réfèrent à cette niveau élevé de contrôle de la simultanéité de l'article pour plus de détails.

En particulier, jeter un oeil à variables atomiques .

Related SE questions:

Volatile Vs Atomique

Volatile boolean vs AtomicBoolean

la Différence entre la volatilité et la synchronisation en Java

4
répondu Ravindra babu 2017-05-23 10:31:37

volatile valeur de la variable d'accès direct à partir de la mémoire principale. Il ne doit être utilisé que dans un environnement multi-threading. la variable statique sera chargée une fois. Si elle est utilisée dans un environnement de thread simple, même si la copie de la variable sera mise à jour et il n'y aura aucun mal à y accéder car il n'y a qu'un seul thread.

maintenant, si la variable statique est utilisée dans un environnement multi-threading, il y aura des problèmes si l'on s'attend à un résultat désiré. Comme chaque le fil a leur propre copie alors n'importe quel incrément ou décrément sur la variable statique d'un fil ne peut pas refléter dans un autre fil.

si l'on s'attend à des résultats souhaités de la variable statique, puis utiliser volatile avec statique en multi-filetage, alors tout sera résolu.

0
répondu Aslam anwer 2017-03-27 07:15:32

Si nous déclarons une variable statique, il n'y aura qu'une 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(puisqu'il n'y a qu'un seul emplacement mémoire attribué à la variable).

Si une variable est déclarée comme volatile, tous les threads ont leur propre copie de la variable, mais la valeur est prise à partir de la mémoire principale.Donc, la valeur de la variable dans tous les threads seront les mêmes.

Donc, dans les deux cas, le point principal est que la valeur de la variable est identique sur tous les threads.

-1
répondu Jitendra Nalwaya 2011-04-20 06:04:22