Pourquoi est-List<T> pas thread-safe?
À partir du site suivant:
http://crfdesign.net/programming/top-10-differences-between-java-and-c
Malheureusement,
List<>
n'est pas thread-safe (C#’sArrayList
et de Java
Vector
sont thread-safe). C# a aussi unHashtable
; la version générique est:
Ce qui rend List<T>
pas thread-safe? Est-il problème de mise en œuvre sur .NET framework de l'ingénieur de la partie? Ou sont les génériques pas thread-safe?
- Selon MSDN ArrayList et List(Of T) ont le même fil de sécurité.
ArrayList
les Synchronisé wrapper cependant.
Vous devez vous connecter pour publier un commentaire.
Vous avez vraiment besoin de classer Java Vecteur du type de fil de sécurité. Javas Vecteur est sûr pour être utilisé à partir de plusieurs threads, car il utilise la synchronisation sur les méthodes. L'état ne sera pas endommagé.
Cependant, Java est le vecteur de l'utilité est limitée à partir de plusieurs threads sans synchronisation supplémentaire. Considérons, par exemple, le simple fait de lire un élément à partir d'un vecteur
Cette méthode ne sera pas corrompu l'état du vecteur, mais aussi il n'est pas correct. Rien n'empêche un autre thread de la mutation du vecteur entre l'instruction si un get() de l'appel. Ce code peut et sera finalement échouer en raison d'une condition de course.
Ce type de synchronisation est seulement utile dans une poignée de scénarios, et il est certainement pas bon marché. Vous payez une malformation des prix pour la synchronisation, même si vous n'utilisez pas plusieurs threads.
.Net a choisi de ne pas payer ce prix par défaut pour un scénario d'une utilité limitée. Au lieu de cela, elle a choisi de mettre en œuvre un verrou Liste libre. Les auteurs sont responsables pour tout ajout de la synchronisation. C'est plus proche de C++de modèle de "ne payez que pour ce que vous utilisez"
Récemment, j'ai écrit quelques articles sur les dangers de l'utilisation des collections avec seulement synchronisation interne, tels que Java est le vecteur.
Référence Vecteur fil de sécurité: http://www.ibm.com/developerworks/java/library/j-jtp09263.html
Vector
codé dans les bibliothèques java ne peut pas être utilisé en toute sécurité dans la manière que vous décrivez sans verrouillage. C'est juste pas possible parce que chaque résultat que vous trouvez n'est pas valide au moment où vous le lisez.Count
peut souvent être utile en dehors de verrous, à des fins de début de la sortie de communes des cas.Count()
contient une valeur qui serait suffisant pour ce que l'on doit faire, on peut éviter un verrouillage de l'acquisition/cycle de publication dans le cas où il n'y a rien à faire. Si l'état normal des affaires est pour la collection ne contient pas assez de données pour être en vaut la transformation, cette optimisation peut parfois offrir des avantages importants. De temps en temps on va vérifierCount()
, décider d'acquérir le verrou, cochez la caseCount()
de nouveau, et de trouver que les données ont disparu, donc il n'y a plus rien à voir, mais ...Count
peut être utilisé comme un bon verrouillage de l'évitement de la tour. Mais cette remarque ne fait pas travailler avecvector
commesize
lui-même acquiert un verrou.Pourquoi serait il être thread-safe? Pas chaque classe est. En fait, par défaut, les classes sont pas thread-safe.
Être thread-safe signifie que toute opération de modification de la liste devra être enclenchées contre les accès simultanés. Ce serait nécessaire, même pour ceux qui répertorie qui ne pourront jamais être utilisé que par un seul thread. Ce serait très inefficace.
C'est simplement une décision de conception pour mettre en œuvre les types pas thread-safe. Les collections de fournir les biens
SyncRoot
de l'interfaceICollection
et laSynchronized()
méthode sur certaines collections explicitement, de synchroniser les types de données.Utilisation
SyncRoot
pour verrouiller un objet en multithread environnements.Utilisation
collection.Synchronized()
pour obtenir un "thread-safe" wrapper pour la collection.La course la condition de possibilité JaredPar mentionne, c'est effrayant conséquence de s'appuyer sur le Vecteur est censé thread-safety. C'est le genre de chose que les résultats dans le "chaque neuvième mardi de l'application ne quelque chose de bizarre"-sorte de rapport de défaut qui va vous conduire fou.
Il y a un certain nombre de vraiment thread-safe collections venir dans .Net 4, avec un intéressant effet secondaire qu'ils permettent à un seul thread modification de la collecte lors de l'énumération, mais il y a un performances qui vient avec fil-sécurité, parfois, une assez grosse.
De sorte que la chose logique pour un cadre de développeur à faire est de garder la classe aussi performante que possible pour les 95% des utilisateurs qui ne sera probablement pas faire le filetage et de s'appuyer sur ceux qui font le multi-thread pour savoir ce qu'ils ont à faire pour la garder en sécurité.
Pour de vrai fil de sécurité,
List<>
et d'autres types de collection aurait besoin d'être immuable. Avec le parallèle des extensions .NET à venir .NET 4.0 nous allons voir thread-safe versions les plus couramment utilisés par les collections.Jon Skeet évoque certains aspects de cette.
utilisation SynchronizedCollection il fournit également un Constructeur de Paramètre pour l'utilisation partagée de synchronisation 🙂