.net - current - thread safe dictionary
¿Por qué List<T> no es seguro para subprocesos? (6)
Desde el siguiente sitio:
http://crfdesign.net/programming/top-10-differences-between-java-and-c
Desafortunadamente,
List<>
no es seguro para subprocesos (ArrayList
C # yVector
de Java son seguros para subprocesos). C # también tiene unaHashtable
; la versión genérica es:
¿Qué hace que List<T>
no sea seguro para subprocesos? ¿Es un problema de implementación en la parte del ingeniero del framework .NET? ¿O los genéricos no son seguros para subprocesos?
¿Por qué sería seguro para subprocesos? No todas las clases son De hecho, de forma predeterminada, las clases no son seguras para subprocesos.
Ser seguro para subprocesos significaría que cualquier operación que modifique la lista debería estar interconectada contra el acceso simultáneo. Esto sería necesario incluso para aquellas listas que solo serán utilizadas por un solo hilo. Eso sería muy ineficiente.
Es simplemente una decisión de diseño implementar los tipos que no son seguros. Las colecciones proporcionan la propiedad SyncRoot
de la interfaz ICollection
y el método Synchronized()
en algunas colecciones para sincronizar explícitamente los tipos de datos.
Use SyncRoot
para bloquear un objeto en entornos multiproceso.
lock (collection.SyncRoot)
{
DoSomething(collection);
}
Use collection.Synchronized()
para obtener un contenedor seguro para subprocesos para la colección.
La posibilidad de condición de carrera que menciona JaredPar es la aterradora consecuencia de confiar en la supuesta seguridad de hilos de Vector. Es el tipo de cosa que resulta en "cada noveno martes que la aplicación hace algo raro": un informe de varios defectos que te volverá loco.
Hay una serie de colecciones verdaderamente seguras para hilos en .NET 4 , con un interesante efecto secundario que permiten la modificación de un único subproceso de la colección al enumerar , pero hay un rendimiento que viene con la seguridad de hilos, a veces una bonita uno grande.
Entonces, lo lógico para un desarrollador de framework es mantener la clase lo más eficiente posible para el 95% de los usuarios que probablemente no lo harán y confiar en aquellos que hacen multi-thread para saber lo que tienen que hacer para mantener es seguro.
Para una verdadera seguridad de hilos, List<>
y otros tipos de colecciones necesitarían ser inmutables. Con las extensiones paralelas a .NET que salen en .NET 4.0 veremos versiones seguras para hilos de las colecciones más comúnmente usadas. Jon Skeet toca algo de esto.
Realmente necesita clasificar el tipo de seguridad de subprocesos de Vector de Java. Javas Vector es seguro para ser utilizado desde múltiples hilos porque usa sincronización en los métodos. El estado no estará dañado.
Sin embargo, la utilidad del vector de Java está limitada por varios hilos sin sincronización adicional. Por ejemplo, considere el simple acto de leer un elemento de un vector
Vector vector = getVector();
if ( vector.size() > 0 ) {
object first = vector.get(0);
}
Este método no dañará el estado del vector, pero tampoco es correcto. No hay nada que impida que otro hilo mute el vector entre el enunciado if y la llamada get (). Este código puede y eventualmente fallará debido a una condición de carrera.
Este tipo de sincronización solo es útil en un puñado de escenarios y ciertamente no es barato. Usted paga un precio notable por la sincronización incluso si no usa múltiples hilos.
.Net optó por no pagar este precio por defecto para un escenario de utilidad limitada. En su lugar, optó por implementar una Lista libre de bloqueo. Los autores son responsables de agregar cualquier sincronización. Está más cerca del modelo de C ++ de "pagar solo por lo que usa"
Recientemente escribí un par de artículos sobre los peligros de usar colecciones con solo sincronización interna, como el vector de Java.
- ¿Por qué las colecciones seguras para hilos son tan difíciles?
- Una API más útil para una colección segura de subprocesos mutables
Seguridad de hilo de Vector de referencia: http://www.ibm.com/developerworks/java/library/j-jtp09263.html
use SynchronizedCollection, también proporciona un Constructor-Parameter para usar una sincronización compartida :)