2012-01-30 3 views
2

J'ai une Hashtable à laquelle plusieurs threads accèdent. Par exemple, regardons trois threads:Concurrence HashTable

Le thread A fait Hash.Insert ("a", nouvel objet());

Le thread B fait Hash.Insert ("b", nouvel objet());

Le thread C fait Hash.Insert ("a", nouvel objet());

Pour certaines raisons, je ne peux pas utiliser un verrou sur l'ensemble Hash

Je ne se soucient de l'ordre ou quel objet sera à la table de hachage à la fin du processus. La seule chose qui m'importe est de ne pas corrompre les données en mettant à jour la même cellule à partir de différents threads.

Quelles sont mes options? ou n'est-ce pas un problème et le HashTable gère cela tout seul et garde les données intactes.

+0

"Pour certaines raisons, je ne peux pas utiliser un verrou sur l'ensemble du hachage" Pouvez-vous expliquer cette exigence? Est-ce seulement la performance? – CodesInChaos

+0

@CodeInChaos il peut y avoir des milliers de demandes simultanément, donc je suis plus inquiet de la famine car il est possible pour un thread qui a acquis un verrou de ne jamais avoir le temps processeur ... –

+0

Il est hautement improbable que vous fassiez l'expérience de non-FIFO traitement des serrures.Voir http://stackoverflow.com/questions/961869/is-there-a-synchronization-class-that-guarantee-fifo-order-in-c. pour un objet de synchronisation qui garantit l'ordre FIFO, ce qui empêchera la famine. –

Répondre

5

Vous pouvez envisager d'utiliser quelque chose comme:

ConcurrentDictionary<string, object> Hash = new ConcurrentDictionary<string, object>(); 

de l'espace de noms System.Collections.Concurrent.

+0

J'y ai pensé mais cela dépend de la façon dont ConcurrentDictionary est implémenté. Est-ce qu'il verrouille le hachage entier? ou est-ce plus sophistiqué? –

+0

@Amit Je suis à peu près sûr que l'implémentation est sans verrou, mais ce n'est bien sûr qu'un détail d'implémentation. Mais il n'y a aucun moyen d'observer directement la différence entre les implémentations de verrouillage et de verrouillage, sauf que le verrouillage est souvent plus rapide. – CodesInChaos

+0

à partir d'un coup d'oeil rapide dans le réflecteur, il semble que le dictionnaire concurrent utilise des verrous de seau et il semble qu'il a plusieurs verrous et chaque nombre de cellules obtient un verrou. Espérons que c'est assez bon –

3

ConcurrentDictionary devrait fonctionner pour vous. Il n'est pas verrouillé, mais il ne "verrouille pas tout le hachage" sauf dans certaines situations.

Il utilise deux collections, un tableau de verrouillage et une collection de compartiments de hachage.
Le nombre de compartiments de verrouillage peut être contrôlé en définissant le niveau de concurrence, et le nombre initial de compartiments de hachage peut être contrôlé en définissant la capacité initiale. (ce sont les deux paramètres du constructeur).

Chaque godet de la rangée de serrures recouvre plusieurs godets (bien au moins un) à l'aide d'un simple hachage modulo.

La seule fois que les serrures de dictionnaire simultanés tous les seaux de verrouillage sont:

  1. Lors du redimensionnement des seaux de hachage.
  2. Lors de la lecture de la propriété publique Keys.
  3. Lors de la lecture de la propriété publique Values.
  4. Lors de la lecture de la propriété Count Count.
  5. Lors de la lecture de la propriété publique IsEmpty.
  6. Lors de l'appel Clear().
  7. Lors de la sérialisation.

À l'exception du redimensionnement, ils sont tous facilement évitables.

Le redimensionnement peut être évité si vous pouvez prévoir le nombre maximum d'éléments dans le dictionnaire.