42 votes

Pourquoi est la liste <T> pas thread-safe?

à partir de ce site:

http://crfdesign.net/programming/top-10-differences-between-java-and-c

Malheureusement, la Liste des<> n'est pas thread-safe (C#liste de tableaux et de Java Vecteur sont thread-safe). C# a aussi un Hashtable; la version générique est:

ce qui fait 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?

67voto

JaredPar Points 333733

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

Vector vector = getVector();
if ( vector.size() > 0 ) { 
  object first = vector.get(0);
}

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 va 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

20voto

John Saunders Points 118808

Pourquoi serait- il thread-safe? Toutes les classes ne sont pas. En fait, par défaut, les classes ne sont pas thread-safe.

Être thread-safe signifierait que toute opération modifiant la liste devrait être interconnectée avec un accès simultané. Cela serait nécessaire même pour les listes qui ne seront jamais utilisées que par un seul thread. Ce serait très inefficace.

9voto

Daniel Brückner Points 36242

C'est simplement une décision de conception d'implémenter les types non thread-safe. Les collections fournissent la propriété SyncRoot de l'interface ICollection et la méthode Synchronized () sur certaines collections pour la synchronisation explicite des types de données.

Utilisez SyncRoot pour verrouiller un objet dans des environnements multithreads.

 lock (collection.SyncRoot)
{
   DoSomething(collection);
}
 

Utilisez collection.Synchronized () pour obtenir un wrapper thread-safe pour la collection.

2voto

Abhijeet Patel Points 2116

Pour une véritable sécurité des threads, List <> et les autres types de collection doivent être immuables. Avec les extensions parallèles à .NET disponibles dans .NET 4.0, nous verrons des versions thread-safe des collections les plus utilisées. Jon Skeet aborde certaines de ces questions.

2voto

Ragoczy Points 1339

La course-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 à la modification de la collecte lors de l'énumération, mais il y a un gain de performance qui vient avec fil-sécurité, parfois, une assez grosse.

Donc, la logique d'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é.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X