Utilisation de ConcurrentHashMap, quand la synchronisation est-elle nécessaire?
J'ai un ConcurrentHashMap où je ne les suivants:
sequences = new ConcurrentHashMap<Class<?>, AtomicLong>();
if(!sequences.containsKey(table)) {
synchronized (sequences) {
if(!sequences.containsKey(table))
initializeHashMapKeyValue(table);
}
}
Ma question est: est - il inutile de faire de l'extra
if(!sequences.containsKey(table))
Vérifier à l'intérieur de la synschronized bloc de sorte que les autres threads habitude initialiser la même table de hachage de la valeur?
Peut-être que la vérification est nécessaire et je fais de mal? Il semble un peu idiot ce que je fais, mais je pense que c'est nécessaire.
source d'informationauteur Per Stilling | 2013-02-13
Vous devez vous connecter pour publier un commentaire.
Tous opérations sur un ConcurrentHashMap sont thread-safe, mais les opérations thread-safe ne sont pas composables. Vous essayer de faire atomique d'une paire d'activités: vérification pour quelque chose dans la carte et, dans le cas où il n'est pas là, mettre quelque chose là-bas (je suppose). Donc la réponse à vos questions est ouivous avez besoin de vérifier à nouveau, et que ton code a l'air correct.
Vous devriez être en utilisant la putIfAbsent méthodes de
ConcurrentMap
.Fonctionnelle puristes d'entre nous, le ci-dessus peut être simplifiée (ou peut-être complexified):
Et dans Java 8, nous pouvons éviter la création inutile d'un
AtomicLong
:Vous ne pouvez pas obtenir verrou exclusif avec ConcurrentHashMap. Dans de tels cas, il est mieux d'utiliser Synchronisé HashMap.
Il y a déjà un atomique méthode pour mettre à l'intérieur ConcurrentHashMap si l'objet n'est pas déjà là;
putIfAbsent
Je vois ce que vous avez fait 😉 la question est de ne vous voir vous-même?
Tout d'abord tout ce que vous avez utilisé quelque chose qui s'appelle "la Double vérification de verrouillage modèle". Où vous avez accès rapide (première contient) qui n'a pas besoin de synchronisation des cas, il est satisfait et lent cheminement qui doit être synchronisé parce que vous n'avez opération complexe. Votre opération consiste à vérifier si quelque chose est à l'intérieur de la carte, puis y mettre quelque chose /initialisation. Donc, il n'est pas question que ConcurrentHashMap est thread-safe pour une seule opération, car vous n'deux opérations simples qui doivent être traités à l'unité, donc oui, ce bloc synchronisé est correcte et il pourrait être synchronisés par autre chose, par exemple
this
.Dans Java 8, vous devez être en mesure de remplacer la double vérification de verrouillage avec
.computeIfAbsent
:Créer un fichier nommé dictionary.txt avec le contenu suivant:
Ici, nous avons:
Nombre de mots commençant par "a": 3
Nombre de mots commençant par "b": 3
Total nombre de mots: 6
Maintenant exécuter le programme suivant: java WordCount test_dictionary.txt 10
}
Vous voir varient comme indiqué ci-dessous:
{a=2, b=3}
Total nombre de mots: 6
Achevé en 77 millisecondes
{a=3, b=3}
Total nombre de mots: 6
Maintenant en commentaire ConcurrentHashMap à la ligne 13, décommentez la ligne du dessus et exécutez à nouveau le programme.
Vous voir déterministe compte.