Может ли список <t>быть доступен для нескольких потоков? - PullRequest
9 голосов
/ 22 декабря 2010

Я планирую поделиться списком между несколькими потоками.Список будет заблокирован во время изменений, которые происходят нечасто.Существует ли проблема безопасности потока, если несколько итераций выполняются из разных потоков в списке одновременно?

Ответы [ 4 ]

11 голосов
/ 22 декабря 2010

Если вы можете (если вы можете использовать .NET 4, то есть), используйте BlockingCollection<T>:

Предоставляет возможности блокировки и ограничения для поточно-ориентированных коллекций, которые реализуютIProducerConsumerCollection<T>.

Если нет, то полностью инкапсулируйте список и добавьте потокобезопасные методы, которые обращаются к состоянию List<T>'s.Не делайте ссылку на список общедоступной и не возвращайте ее из каких-либо методов - всегда инкапсулируйте ссылку, чтобы вы могли гарантировать, что вы блокируете весь доступ к нему.

6 голосов
/ 22 декабря 2010

A List<T> не является потокобезопасным классом, но если вы будете блокировать его каждый раз при чтении / записи в него, проблем не будет.Согласно документации:

Открытые статические (Shared в Visual Basic) члены этого типа являются поточно-ориентированными.Ни один из членов экземпляра не гарантированно является потокобезопасным.

A List<T> может поддерживать несколько считывателей одновременно, если коллекция не изменена.Перечисление через коллекцию по сути не является потокобезопасной процедурой.В редком случае, когда перечисление конкурирует с одним или несколькими доступами на запись, единственный способ обеспечить безопасность потока - заблокировать коллекцию в течение всего перечисления.Чтобы обеспечить доступ к коллекции из нескольких потоков для чтения и записи, необходимо реализовать собственную синхронизацию.

4 голосов
/ 22 декабря 2010

List<T> обычно не является потокобезопасным. Наличие нескольких читателей не вызовет никаких проблем, однако вы не можете писать в список, пока он читается. Таким образом, вам нужно заблокировать как чтение, так и запись, или использовать что-то вроде System.Threading.ReaderWriterLock (что позволяет использовать несколько считывателей, но только одного записывающего).

1 голос
/ 22 декабря 2010

Это может быть чтение из нескольких потоков одновременно, если это то, что вы просите.Рассмотрим блокировку читателя-писателя, если так.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...