Question

est

final Map<Integer,Map<String,Integer>> status = new ConcurrentHashMap<Integer, Map<String,Integer>>();
Map<Integer,Map<String,Integer>> statusInner = new ConcurrentHashMap<Integer, Map<String,Integer>>();
status.put(key,statusInner);

la même chose que

volatile Map<Integer,Map<String,Integer>> status = new ConcurrentHashMap<Integer,   Map<String,Integer>>();
Map<Integer,Map<String,Integer>> statusInner = new ConcurrentHashMap<Integer, Map<String,Integer>>();
status.put(key,statusInner);

dans le cas où la carte intérieure est accessible par différents threads?

ou est encore quelque chose comme cela nécessaire:

volatile Map<Integer,Map<String,Integer>> status = new ConcurrentHashMap<Integer, Map<String,Integer>>();
volatile Map<Integer,Map<String,Integer>> statusInner = new ConcurrentHashMap<Integer, Map<String,Integer>>();
status.put(key,statusInner);

Dans le cas où l'on est pas un « cascade » carte, ont en fin de finale et volatile le même effet que de faire shure toutes les discussions voient toujours le contenu correct de la carte ... Mais qu'advient-il si la carte contient iteself une carte, comme dans l'exemple ... Comment puis-je faire shure que la carte intérieure est correctement « mémoire délimitée par des barrières »?

Tanks! Tom

Était-ce utile?

La solution

volatile affecte uniquement la capacité des autres threads de lire la valeur des variables qu'il est attaché. Il ne modifie en rien la capacité d'un autre thread pour voir les clés et les valeurs de la carte. Par exemple, je pourrais avoir un volatile int[]. Si je change la référence i.e.. si je change le tableau réel qu'il pointe à d'autres threads lecture du tableau sont garantis pour voir ce changement. Cependant, si je change le troisième élément du tableau de telles garanties ne sont faites.

Si status est final, la construction de la classe contenant une relation de type happens-before avec une lecture ultérieure, de sorte qu'ils sont en mesure de voir la valeur de l'état. De même lit tout à votre variable volatile sont garantis pour voir la dernière affectation de référence. Il est à la différence de vous échanger la carte réelle autour très souvent, plus comme vous êtes juste en train de changer les clés et les séjours d'ensemble d'objets de la carte comme est.

Pour cette question, alors, nous devons consulter la documentation ConcurrentHashMap:

opérations de recherche (y compris get) généralement ne pas bloquer, peut donc se chevaucher avec des opérations de mise à jour (y compris mettre et supprimer). Récupérations reflètent la les résultats du plus récent les opérations de mise à jour sur leur tenue apparition.

est un peu curieusement formulée, mais l'essentiel est que toute opération de get dont l'apparition est après un peu le retour de l'opération de put est garanti pour voir les résultats de cette vente. Donc, vous n'avez même pas besoin d'un volatile sur la carte extérieure; Quoth JLS:

Un fil qui ne peut voir une référence à un objet après que l'objet a été est complètement initialisés garantie pour voir correctement le valeurs initialisées pour que son objet champs final.

Résumé

A final sur la carte externe est suffisante.

Autres conseils

Il est intéressant de regarder Google-collections et, en particulier, MapMaker qui vous permet de configurer intelligemment et de créer des cartes. Être en mesure de configurer des valeurs faibles pour permettre une meilleure collecte des ordures et des temps d'expiration, de sorte que vous pouvez utiliser Maps pour la mise en cache efficace, est brillante. Comme les cartes qui fait MapMaker (: p). Ont les mêmes propriétés que ConcurrentHashMap, vous pouvez être heureux avec son fil de sécurité

final mapMaker = new MapMaker().weakValues(); //for convenience, assign
final Map<Integer,Map<String,Integer>> status = mapMaker.makeMap();
status.put(key, mapMaker.<String, Integer>makeMap());

S'il vous plaît note, vous voudrez peut-être regarder votre définition de statusInner, car il ne semble pas juste.

Je pense que la meilleure réponse est que volatile n'est pas un moyen d'assurer la sécurité-fil.

L'utilisation ConcurrentHashMap est à peu près tout ce que vous avez besoin. Oui, faire la référence au Map niveau supérieur final si vous le pouvez, mais volatile n'est pas nécessaire en tout état de cause. Le deuxième niveau de référence de Map sont à l'intérieur de l'entreprise ConcurrentHashMap pour obtenir le droit, et l'on suppose qu'il fait.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top