Страницы

Поиск по вопросам

суббота, 14 декабря 2019 г.

Почему нет ConcurrentList<T>?

#c_sharp #net #многопоточность


В .NET есть такая структура как потокобезопасный словарь ConcurrentDictionary. А
вот потокобезопасного списка почему-то нет? Может кто-то знает почему? Заранее спасибо
    


Ответы

Ответ 1



Почему нет ConcurrentList? Ответ в том, что все Concurrent* коллекции в пространстве имен System.Collections.Concurrent имеют чрезвычайно эффективные и масштабируемые реализации. То есть, внутри они используют такие облегченные примитивы синхронизации, как SpinLock и SpinWait. Фактически, реализации ConcurrentQueue и ConcurrentStack не используют вообще никаких локов. Это привело к тому, что написание такого же эффективного списка стало нелегкой задачей. Как результат, отсутствует тип ConcurrentList, потому что его реализация не будет ощутимо лучше List с классическим локом (который будет довольно тяжелым) C# 5.0 Unleashed Bart De Smet

Ответ 2



В интерфейсе IList есть методы для работы с элементами по их индексу. Однако в многопоточной среде элементы в любой момент могут быть удалены или сдвинуты со своего места, а значит доступ по индексу теряет смысл. Поэтому потокобезопасного списка ConcurrentList нет, но есть потокобезопасная коллекция BlockingCollection.

Ответ 3



Я не знаю точной причины, остаётся только гадать. На мой взгляд, такой структуры нет из-за того, что List в C# содержит элементы одним куском(contiguous memory), а реализовать такую структуру в терминах lock-free довольно сложно, видимо. Все примеры lock-free или wait-free структур, что я видел были основаны на узлах, которые ссылались друг на друга. Видимо, это довольно сложно сделать со структурой, у которой нет узлов, поэтому решили, что «овчинка выделки не стоит». Вот нашёл описание lock-free vector для С++, что подойдёт для List из C#, в целом.

Ответ 4



Это сделано в угоду производительности. Если есть именно необходимость потокобезопасного списка используйте CopyOnWriteArrayList A thread-safe variant of {@link java.util.ArrayList} in which all mutative operations ({@code add}, {@code set}, and so on) are implemented by making a fresh copy of the underlying array.

Комментариев нет:

Отправить комментарий