Y a-t-il une différence entre une volatile
référence d'objet et AtomicReference
au cas où j'utiliserais simplement get()
et set()
-méthodes de AtomicReference
?
java
concurrency
auramo
la source
la source
Non, il n'y en a pas.
La puissance supplémentaire fournie par AtomicReference est la méthode compareAndSet () et ses amis. Si vous n'avez pas besoin de ces méthodes, une référence volatile fournit la même sémantique que AtomicReference.set () et .get ().
la source
Il existe plusieurs différences et compromis:
L'utilisation d'un
AtomicReference
get / set a la même sémantique JMM qu'un champ volatile (comme l'indique javadoc), maisAtomicReference
est un wrapper autour d'une référence, donc tout accès au champ implique une poursuite de pointeur supplémentaire .L' empreinte mémoire est multipliée (en supposant un environnement de POO compressé, ce qui est vrai pour la plupart des machines virtuelles):
AtomicReference
= 4b + 16b (en-tête d'objet 12b + champ de référence 4b)AtomicReference
offre une API plus riche qu'une référence volatile. Vous pouvez récupérer l'API pour la référence volatile en utilisant unAtomicFieldUpdater
, ou avec Java 9 aVarHandle
. Vous pouvez également atteindre directementsun.misc.Unsafe
si vous aimez courir avec des ciseaux.AtomicReference
lui-même est implémenté en utilisantUnsafe
.Alors, quand est-il bon de choisir l'un plutôt que l'autre:
AtomicReference
/AtomicFieldUpdater
/Unsafe
où vous avez tendance à payer en lisibilité et à prendre des risques pour votre gain de performances. Si ce n'est pas une zone sensible, allez-yAtomicReference
. Les rédacteurs de bibliothèque utilisent généralement une combinaison de ces méthodes en fonction des JDK ciblés, des restrictions d'API attendues, des contraintes de mémoire, etc.la source
Le code source JDK est l'un des meilleurs moyens de répondre à de telles confusions. Si vous regardez le code dans AtomicReference, il utilise une variable volatie pour le stockage d'objets.
Donc, évidemment, si vous allez simplement utiliser get () et set () sur AtomicReference, c'est comme utiliser une variable volatile. Mais comme l'ont commenté d'autres lecteurs, AtomicReference fournit une sémantique CAS supplémentaire. Alors, décidez d'abord si vous voulez ou non la sémantique CAS, et si vous ne le faites que, utilisez AtomicReference.
la source
AtomicReference
fournit des fonctionnalités supplémentaires qu'une variable volatile simple ne fournit pas. Comme vous avez lu l'API Javadoc, vous le saurez, mais il fournit également un verrou qui peut être utile pour certaines opérations.Cependant, à moins que vous n'ayez besoin de cette fonctionnalité supplémentaire, je vous suggère d'utiliser un
volatile
champ simple .la source
volatile
champ peut être utilisé comme n'importe quel champ normal alors que l'accès à la valeur dans unAtomicReference
nécessite un passage parget
et desset
méthodes.Parfois, même si vous n'utilisez que des get et des ensembles, AtomicReference peut être un bon choix:
Exemple avec volatile:
L'implémentation avec AtomicReference vous donnerait une synchronisation copie sur écriture gratuitement.
On pourrait dire que vous pourriez toujours avoir une copie correcte si vous remplaçiez:
avec:
Cependant, le second est plus susceptible d'être supprimé par quelqu'un accidentellement à l'avenir pendant le "nettoyage du code".
la source