9
votes

Pourquoi Concurrenthashmap.PutFabsent est-il sûr?

J'ai lu pour la concurrent depuis hier et je ne sais pas beaucoup de choses ... Cependant, certaines choses commencent à se dégager ...
Je comprends pourquoi la double vérification Verrouillage n'est pas sûre (je me demande quelle est la propagatique de se produire de manière rare) mais volatile corrige le problème dans 1,5 + ....
Mais je me demande si cela se produit avec putifabsent

comme ... xxx

alors cela garantit que myobj serait 100% intialisé lorsqu'un autre thread fait un chashm.get () ??? Parce qu'il pourrait avoir une référence n'est pas complètement initialisée (le problème de verrouillage de la double vérification)


0 commentaires

4 Réponses :


1
votes

Je ne suis pas un expert à ce sujet, mais en regardant la mise en œuvre du segment dans Concurrenthashmap Je vois que le champ volatile Compte semble être utilisé pour assurer une visibilité correcte entre les threads. Toutes les opérations de lecture doivent lire le champ et toutes les opérations d'écriture doivent y écrire. Des commentaires dans la classe: xxx


0 commentaires

5
votes

Si vous invoquez Concurrenthashmap.get (clé) et renvoie un objet, cet objet est garanti pour être complètement initialisé. Chaque placement (ou putifabsent) obtiendra un verrou de seau spécifique et apportera l'élément aux entrées du godet.

Maintenant, vous pouvez passer par le code et remarquer que la méthode Obtention n'obtient pas ce même verrou. Donc, vous pouvez faire valoir qu'il peut y avoir une lecture obsolète, ce n'est pas vrai non plus. La raison ici est que la valeur dans l'entrée elle-même est volatile. Donc, vous serez sûr d'obtenir le meilleur jour à jour.


5 commentaires

Donc, si je comprends bien, il n'y a pas de problème, comme dans la double vérification classique paradigme de verrouillage?


@Parhs: Droite, il n'y a pas de problème.


Vous avez raison. Vous avez réellement répondu à votre question dans votre question avec «mais la volatilité corrige le problème dans 1.5 +» car la valeur renvoyée à partir de la CCHM est une valeur volatile, elle est également sûre de l'initialisation partielle.


@Johnvint j'ai une question similaire ici sur effectuer et mettre en place atomiquement sur CHM. Pouvez-vous m'aider là-bas?


@david j'ai répondu à votre question là-bas. La seule fois, vous aurez besoin de la logique de contrôle, puis si elle doit être mémoée.



5
votes

putifabsent méthode dans Concurrenthashmap est une méthode check-si--absent-jet. C'est une opération atomique. Mais pour répondre à la partie suivante: "Ensuite, cela garantit que MyObJ serait complètement intialisé lorsqu'un autre thread est un autre fil.get ()". Habituellement, il existe une priorité avant la priorité, c'est-à-dire si l'appelant reçoit d'abord avant que l'objet soit placé sur la carte, alors null serait renvoyé, sinon la valeur serait renvoyée.


2 commentaires

null à retourner ne serait pas une PRB, mais une référence à un objet initialisé non construit serait. (le problème avec double vérification Verrouillage)


+1 upvoted pour "atomique" atomique s'occupe de la commande de threads, de sorte que la méthode .put () n'est pas appelée deux fois Concurrenthashmape s'occupe de la synchronisation des threads de méthode de l'écrivain .put ()



2
votes

La partie pertinente de la documentation est la suivante:

Effets de cohérence de la mémoire: comme avec Autres collections simultanées, actions dans un fil avant de placer un objet dans un concurrentMap comme clé ou valeur arriver - avant les actions postérieures à l'accès ou l'enlèvement de cet objet de la concurrence dans une autre Fil.

- java.util .ConCurrentMap

Alors, oui, vous avez votre arrive-avant relation.


0 commentaires