2008-11-12 14 views
5

Para recapitular para esos gurús .NET que no saben la API de Java:¿.NET tiene una implementación de diccionario que es equivalente a ConcurrentHashMap de Java?

ConcurrentHashMap en Java tiene métodos atómicos (es decir, no requieren bloqueo externo) para el Mapa común las operaciones de modificación, tales como:

putIfAbsent(K key, V value) 
remove(Object key, Object value) 
replace(K key, V value) 

Se también permite la iteración sobre el conjunto de claves sin bloqueo (toma una copia al comienzo de la iteración) y las operaciones get() generalmente se pueden intercalar con llamadas al put() sin bloqueo (usa el diseño de bloqueo de grano fino IIRC).

De todos modos, mi pregunta es: .NET tiene una implementación del diccionario equivalente?

Supongo que, en general, me gustaría saber si .NET tiene un conjunto más general de librerías de colección segura para hilos. O utilidades de simultaneidad en general, equivalentes a las bibliotecas Doug Leajava.util.concurrent.

+0

¿Realmente necesitas la etiqueta de Java aquí? –

+0

Georgy - tienes razón - es una pregunta de .NET, no de Java. Etiqueta eliminada – serg10

+0

Mi proyecto http://concurrent.codeplex.com/ tiene un diccionario Sharded, que permite múltiples lectores y escritores, y permite transacciones en ciertos valores. Aunque está muy en desarrollo ... – Martin

Respuesta

2

No es que yo sepa. Lo más parecido a lo que está buscando probablemente sea el método Sincronizado de Hashtable, que devuelve una especie de envoltorio seguro para subprocesos alrededor de la tabla hash. Sin embargo, solo es seguro para subprocesos para varios escritores o lectores múltiples. Si recuerdo correctamente, una mezcla de escritores y lectores no será segura para subprocesos.

3

EDITAR: Esto fue escrito antes de que se lanzara .NET 4, cuando obviamente hay ConcurrentDictionary. Lo dejo aquí como referencia para aquellos que necesitan .NET 3.5.

No conozco ningún equivalente a ConcurrentHashMap.

En términos de utilidades generales de concurrencia - .NET siempre ha proporcionado un poco más de lo básico, que Java utilizadas para proporcionar, en términos de Mutex, ManualResetEvent, AutoResetEvent y ReaderWriterLock; más recientemente (.NET 2.0) Semaphore y (.NET 3.5) ReaderWriterLockSlim, así como el grupo de subprocesos de todo el proceso, por supuesto.

Una reorganización más grande vendrá en .NET 4.0 cuando lleguen las Extensiones Paralelas - eso debería hacer que la concurrencia sea mucho más simple. Del mismo modo, el Coordination and Concurrency Runtime finalmente se liberó de los grilletes de Microsoft Robotics Studio, aunque no tengo claro exactamente hacia dónde se dirige (ya sea que sea parte de .NET o una biblioteca separada).

+0

Tenía la impresión (desde blogs públicos de MSDN) de que estaba destinado a ser una parte central de .NET 4.0. –

+0

Gracias por su respuesta Jon. Paralelo Extensiones parece muy interesante. Para que quede claro, no estoy trolling, esta no es una queja de "Java tiene mejores bibliotecas que .net". Soy nuevo en .net y estoy ansioso por ver lo que está disponible de manera inmediata. – serg10

+0

Marc: ¿El CCR como parte de .NET 4.0? ¡Los enlaces serían bienvenidos! Serg: No te preocupes, no lo tomé de esa manera :) –

2

Personalmente, encuentro que tener métodos individuales sincronizados generalmente no es tan útil como parece.

Comúnmente, es posible que desee hacer un "obtener" y "poner" relacionado en una sucesión estrecha, y si otro hilo está buscando los mismos valores, tiene una carrera de subprocesos inmediata. Del mismo modo (dependiendo de la situación) no quiere alguien leyendo los valores en los que está trabajando.

Para un enfoque amplio, el simple uso de un externa Monitor (lock(...) puede funcionar bien para muchas situaciones. Es simple, ligero y menos que esté bajo carga de hilo grueso, más que adecuada.

Para escenarios más complejos, cosas como ReaderWriterLockSlim, etc. son más flexibles.Pero comenzaría de forma simple, y solo cambiaría las cosas si los perfiles muestran que hay un problema genuino de contención.

Como señala Jon, con Parallel Extension viene una nueva serie de dispositivos de sincronización de alto rendimiento; por lo que puedo ver (por ejemplo here, y herehere), esto es parte de .NET 4.0

+1

En ConcurrentHashMap de Java, los métodos individuales get, replace, putIfAbsent, etc. no están sincronizados. Usan algoritmos que no son de bloqueo para funcionar sin bloquear en la mayoría de las situaciones de carga. Echaré un vistazo a ReaderWriterLockSlim - gracias por la sugerencia. – serg10

+0

No los llamaría exactamente "alto rendimiento". :-) –

16

El entrante .Net 4.0 tiene una clase ConcurrentDictionary, tiene un método conveniente GetOrAdd.

public TValue GetOrAdd(
    TKey key, 
    Func<TKey, TValue> valueFactory 
) 

Muy útil para cachés de servidores globales.

+2

para cachés de servidores globales podría ser mejor usar un objeto 'MemoryCache'; de lo contrario, podría perder memoria si no se eliminan manualmente los objetos a los que se hace referencia del' ConcurrentDictionary' – Sebastian

+0

Tenga en cuenta que valueFactory para GetOrAdd se puede ejecutar varias veces y * * no es atómico ** como se demostró [Aquí] (http://ayende.com/blog/4802/concurrentdictionary-getoradd-may-call-the-valuefactory-method-more-than-once) y [Aquí] (http : //geekswithblogs.net/BlackRabbitCoder/archive/2011/02/17/c.net-little-wonders-the-concurrentdictionary.aspx) – Anastasiosyal

Cuestiones relacionadas