Maison  >  Article  >  développement back-end  >  Explication détaillée de l'utilisation de l'exemple de collection de dictionnaires de synchronisation multithread ConcurrentDictionary

Explication détaillée de l'utilisation de l'exemple de collection de dictionnaires de synchronisation multithread ConcurrentDictionary

零下一度
零下一度original
2017-06-24 09:48:2414208parcourir

Au cours de la période passée, la plupart de mes classes de base utilisaient une combinaison de lock et de Hashtable pour implémenter la gestion des conflits pour les caches multi-threads. Cependant, parfois la combinaison de ces deux n'était pas satisfaisante, la collection avait été ajoutée. Exception, le problème est resté le même après plusieurs traitements du code. Enfin, la collection de dictionnaires synchronisés multithread ConcurrentDictionary introduite après .NET 4.0 a été utilisée et le problème a été résolu avec succès.

1. Utilisez la combinaison de lock et Hashtable pour implémenter

Dans ma classe de base, créez l'objet métier. Généralement, vous pouvez utiliser BLLFactory.Instance pour obtenir l'application du. objet métier correspondant.

var result = BLLFactory<Customer>.Instance.FindFirst();
Console.WriteLine(result.ToJson());

Ainsi, après avoir utilisé BLLFactory.Instance pour construire les objets, placez-les dans la HashTable. Étant donné que la gestion des conflits multithread doit être conçue, un objet de verrouillage doit être conçu. à utiliser pour l'implémenter.

HashTable représente une collection de paires clé/valeur. Dans le .NET Framework, Hashtable est un conteneur fourni par l'espace de noms System.Collections. Il est utilisé pour traiter et représenter des paires clé-valeur. La clé peut généralement être utilisée pour une recherche rapide et la clé est sensible à la casse ; est utilisé pour stocker la valeur correspondant à la clé. Les paires clé-valeur dans Hashtable sont toutes de type objet, donc Hashtable peut prendre en charge tout type de paire clé-valeur, et tout objet non nul peut être utilisé comme clé ou valeur.

En utilisant cette méthode, des conflits d'accès multi-thread se produisent encore du côté Web. Pour cette raison, nous pouvons également utiliser du code de test multi-thread pour tester et reproduire l'erreur,

<.>
            try{
                List<Thread> list = new List<Thread>();for (int i = 0; i < 10; i++)
                {
                    Thread thread = new Thread(() =>{var result = BLLFactory<Customer>.Instance.FindFirst();
                        Console.WriteLine(result.ToJson());
                        Console.WriteLine();
                    });

                    list.Add(thread);
                }for (int i = 0; i < list.Count; i++)
                {
                    list[i].Start();
                }
            }catch(Exception ex)
            {
                LogTextHelper.Error(ex);
            }
Le message d'erreur obtenu par le code de suivi est le suivant.

Par conséquent, comme vous pouvez le voir dans le code ci-dessus, le problème de conflit multithread ne peut pas se produire même avec lock(syncRoot).

2. Utilisez ConcurrentDictionary au lieu de Hashtable

ConcurrentDictionary est l'une des collections thread-safe lancées par .net4.0 et a été publiée avec ConcurrentStack, ConcurrentQueue et d'autres types, leurs versions monothread (thread-unsafe, Queue, Stack, Dictionary) nous seront certainement familières. ConcurrentDictionary<

TKey, TValue> est accessible par plusieurs threads en même temps et est thread-safe. Son utilisation est la même que celle du dictionnaire, mais avec quelques méthodes supplémentaires. ConcurrentDictionary appartient à l’espace de noms System.Collections.Concurrent.

L'espace de noms System.Collections.Concurrent fournit plusieurs classes de collection thread-safe. Lorsque plusieurs threads accèdent simultanément à des collections, ces classes doivent être utilisées à la place des types correspondants dans les espaces de noms System.Collections et System.Collections.Generic .

ConcurrentDictionary Cette classe fournit les méthodes suivantes pour traiter les collections

public bool TryAdd(TKey key, TValue value)public bool TryUpdate(TKey key, TValue newValue, TValue comparisonValue)public TValue this[TKey key] { get; set; }public TValue AddOrUpdate(TKey key, Func<TKey, TValue> addValueFactory, Func<TKey, TValue, TValue> updateValueFactory)    
public TValue AddOrUpdate(TKey key, TValue addValue, Func<TKey, TValue, TValue> updateValueFactory)public TValue GetOrAdd(TKey key, TValue value)public TValue GetOrAdd(TKey key, Func<TKey, TValue> valueFactory)
Utilisez ConcurrentDictionary à la place de Hashtable, jetons un coup d'œil à le code d'implémentation de la classe BLLFactory comme indiqué ci-dessous.

    /// <summary>/// 对业务类进行构造的工厂类/// </summary>/// <typeparam name="T">业务对象类型</typeparam>public class BLLFactory<T> where T : class{//采用ConcurrentDictionary线程安全的集合类来缓存,替代Hashtableprivate static ConcurrentDictionary<string, object> conCurrentCache = new ConcurrentDictionary<string, object>(); /// <summary>/// 创建或者从缓存中获取对应业务类的实例/// </summary>public static T Instance
        {get{string CacheKey = typeof(T).FullName;return (T)conCurrentCache.GetOrAdd(CacheKey, s =>{var bll = Reflect<T>.Create(typeof(T).FullName, typeof(T).Assembly.GetName().Name); //反射创建,并缓存return bll;
                });
            }
        }
    }
Nous pouvons voir que le code a été beaucoup simplifié, et en utilisant le code de test multithread précédent, les données peuvent être obtenues en douceur sans exception.

L'exécution du code peut être implémentée en douceur et il n'y aura aucune exception d'accès multithread survenue avant l'utilisation de Hashtable.

Ce qui précède est l'introduction de ConcurrentDictionary pour remplacer Hashtable pour la mise en cache d'objets multithread. Lorsque le problème peut être résolu en douceur, il s'avère que l'efficacité de l'accès est également améliorée. par rapport à avant, faisant d'une pierre deux coups.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Article précédent:Un contrôle-PropertyGrid très puissantArticle suivant:Un contrôle-PropertyGrid très puissant

Articles Liés

Voir plus