Heim > Artikel > Backend-Entwicklung > Detaillierte Erläuterung der Verwendung von gleichzeitiger Abgabe-Multi-Thread-Synchronisation-Dictionary-Sammlung
In der Vergangenheit verwendeten die meisten meiner Basisklassen eine Kombination aus Sperre und Hashtable, um die Konfliktbehandlung für Caches in Multithreads zu implementieren. Gelegentlich war die Sammlung jedoch nicht zufriedenstellend Ausnahme, das Problem blieb nach der mehrfachen Verarbeitung des Codes gleich. Schließlich wurde die nach .NET 4.0 eingeführte Multithread-Wörterbuchsammlung verwendet und das Problem wurde erfolgreich gelöst.
In meiner Basisklasse das Geschäftsobjekt zu erstellen. Im Allgemeinen können Sie BLLFactory
var result = BLLFactory<Customer>.Instance.FindFirst(); Console.WriteLine(result.ToJson());
Nachdem Sie BLLFactory
HashTable stellt eine Sammlung von Schlüssel/Wert-Paaren dar. Im .NET Framework ist Hashtable ein vom System.Collections-Namespace bereitgestellter Container. Er wird zum Verarbeiten und Darstellen von Schlüssel-Wert-Paaren verwendet. Der Schlüssel kann normalerweise für die Schnellsuche verwendet werden wird zum Speichern des dem Schlüssel entsprechenden Werts verwendet. Die Schlüssel-Wert-Paare in Hashtable sind alle vom Objekttyp, sodass Hashtable jeden Typ von Schlüssel-Wert-Paaren unterstützen kann und jedes Nicht-Null-Objekt als Schlüssel oder Wert verwendet werden kann.
Mit dieser Methode kommt es gelegentlich immer noch zu Multithread-Zugriffskonflikten auf der Webseite. Aus diesem Grund können wir auch Multithread-Testcode verwenden, um den Fehler zu testen und zu reproduzieren,
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); }
Die vom Tracking-Code erhaltene Fehlermeldung lautet wie folgt.
Daher kann das Multithread-Konfliktproblem, wie Sie dem obigen Code entnehmen können, auch bei lock(syncRoot) nicht auftreten.
ConcurrentDictionary ist eine von mehreren Thread-sicheren Sammlungen, die von .net4.0 gestartet wurden und zusammen mit ConcurrentStack veröffentlicht wurden , ConcurrentQueue und andere Typen, ihre Single-Thread-Versionen (Thread-unsicher, Queue, Stack, Dictionary) werden uns auf jeden Fall bekannt sein. ConcurrentDictionary<TKey, TValue> kann von mehreren Threads gleichzeitig aufgerufen werden und ist threadsicher. Seine Verwendung ist die gleiche wie bei Dictionary, jedoch mit einigen weiteren Methoden. ConcurrentDictionary gehört zum System.Collections.Concurrent-Namespace. Der System.Collections.Concurrent-Namespace stellt mehrere threadsichere Sammlungsklassen bereit. Wenn mehrere Threads gleichzeitig auf Sammlungen zugreifen, sollten diese Klassen anstelle der entsprechenden Typen in den Namespaces System.Collections und System.Collections.Generic verwendet werden. ConcurrentDictionary Diese Klasse bietet die folgenden Methoden zum Verarbeiten von Sammlungen Die Ausführung des Codes kann reibungslos implementiert werden und es treten keine Multithread-Zugriffsausnahmen auf, die vor der Verwendung von Hashtable aufgetreten sind. Das Obige ist die Einführung von ConcurrentDictionary als Ersatz für Hashtable für das Multithread-Objekt-Caching. Wenn das Problem reibungslos gelöst werden kann, wird festgestellt, dass auch die Zugriffseffizienz verbessert wird Im Vergleich zu früher schlagen wir zwei Fliegen mit einer Klappe. 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)
Verwenden Sie ConcurrentDictionary anstelle von Hashtable, schauen wir uns das an den Implementierungscode der BLLFactory-Klasse, wie unten gezeigt. /// <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;
});
}
}
}
Wir können sehen, dass der Code stark vereinfacht wurde und mit dem vorherigen Multithread-Testcode die Daten ausnahmslos reibungslos abgerufen werden können.
Das obige ist der detaillierte Inhalt vonDetaillierte Erläuterung der Verwendung von gleichzeitiger Abgabe-Multi-Thread-Synchronisation-Dictionary-Sammlung. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!