блокировка необходима для поиска в словаре?
8454 просмотра
9 ответа
lock(dictionaryX)
{
dictionaryX.TryGetValue(key, out value);
}
блокировка необходима при поиске в словаре?
Программа многопоточная, и при добавлении ключ / значение в dict. Дикт заблокирован.
Автор: DarthVader Источник Размещён: 13.11.2019 11:48Ответы (9)
2 плюса
Блокировка необходима только при синхронизации доступа к ресурсу между потоками. Пока не задействовано несколько потоков, блокировка здесь не требуется.
В контексте обновления и чтения значения из нескольких потоков, да, блокировка абсолютно необходима. Фактически, если вы используете 4.0, вам следует рассмотреть возможность перехода на одну из коллекций, специально предназначенных для одновременного доступа.
Автор: JaredPar Размещён: 22.10.2010 07:4012 плюса
Как уже упоминалось здесь :
Использование TryGetValue () без блокировки небезопасно. Словарь временно находится в состоянии, которое делает его непригодным для чтения, пока другой поток пишет словарь. Словарь будет реорганизовываться время от времени по мере увеличения количества записей в нем. Когда вы читаете в точное время, когда происходит реорганизация, вы рискуете найти неправильное значение для ключа, когда корзины обновлены, но еще не введены значения.
ОБНОВЛЕНИЕ: взгляните на часть «Безопасность потоков» на этой странице .
Автор: Kamyar Размещён: 22.10.2010 07:444 плюса
Как и во многих тонких вопросах программирования, ответ таков: не обязательно.
Если вы только добавляете значения в качестве инициализации, то последующее чтение не нужно синхронизировать. Но, с другой стороны, если вы собираетесь постоянно читать и писать, тогда вам абсолютно необходимо защитить этот ресурс.
Тем не менее, полноценный lock
может быть не лучшим способом, в зависимости от объема трафика, который получает ваш словарь. Попробуйте, ReaderWriterLockSlim
если вы используете .NET 3.5 или выше.
3 плюса
Если у вас есть несколько потоков, обращающихся к Словарю, вам нужно заблокировать обновления и поиск. Причина, по которой вам нужно заблокировать поиск, заключается в том, что обновление может происходить в то же время, когда вы выполняете поиск, а Словарь может находиться в несовместимом состоянии во время обновления. Например, представьте, что у вас есть один поток, который делает это:
if (myDictionary.TryGetValue(key, out value))
{
}
и отдельный поток делает это:
myDictionary.Remove(key);
TryGetValue
Может случиться так, что поток, который выполняет определение, определяет, что элемент находится в словаре, но прежде чем он сможет извлечь элемент, другой поток удаляет его. В результате поток, выполняющий поиск, либо выдаст исключение, либо TryGetValue
вернет, true
но value
будет null
или, возможно, объектом, не соответствующим ключу.
Это только одна вещь, которая может случиться. Нечто подобное может произойти, если вы выполняете поиск в одном потоке, а другой поток добавляет значение, которое вы пытаетесь найти.
Автор: Jim Mischel Размещён: 22.10.2010 07:492 плюса
Используйте новый ConcurrentDictionary<TKey, TValue>
объект, и вы можете забыть о необходимости делать какие-либо блокировки.
1 плюс
Да, вам необходимо заблокировать словарь для доступа в многопоточной среде. Запись в словарь не является атомарной, поэтому он может добавить ключ, но не значение. В том случае, когда вы получаете к нему доступ, вы можете получить исключение.
Автор: Yuriy Faktorovich Размещён: 22.10.2010 07:451 плюс
Если вы используете .Net 4, вы можете заменить его на ConcurrentDictionary, чтобы сделать это безопасно. В пространстве имен System.Collection.Concurrent есть и другие похожие коллекции, предпочтительные, когда вам нужен многопоточный доступ .
Не используйте блокировку «по-своему», если это вариант для вас.
Автор: Steve Townsend Размещён: 22.10.2010 08:330 плюса
Да, вам следует заблокировать, если этот словарь является общим ресурсом для нескольких потоков. Это гарантирует, что вы получите правильное значение, и другой поток не сможет изменить значение на полпути во время вашего вызова Lookup.
Автор: Aamir Размещён: 22.10.2010 07:430 плюса
Да, вы должны заблокировать, если у вас есть многопоточные обновления в этом словаре. Проверьте этот великий пост для деталей: словарь «Безопасный поток» (TKey, TValue)
Но с тех пор как появился ConcurrentDictionary <>, вы можете использовать его либо через .NET 4, либо с помощью Rx в 3.5 (он содержит System.Threading.dll с реализацией для новых многопоточных коллекций)
Автор: Nick Martyshchenko Размещён: 23.10.2010 01:15Вопросы из категории :
- c# Преобразовать десятичную в двойную?
- c# Как рассчитать чей-то возраст в C #?
- c# Как вы сортируете словарь по значению?
- c# В чем разница между int и Integer в Java и C #?
- multithreading Что такое состояние гонки?
- multithreading Что такое тупик?
- multithreading Что такое мьютекс?
- multithreading Как начать потоки в plain C?
- dictionary Как объединить два словаря в одном выражении?
- dictionary Как эффективно перебирать каждую запись на карте Java?
- dictionary Как отсортировать список словарей по значению словаря?
- locking Летучие против блокировки против блокировки
- locking Рекурсивная блокировка (мьютекс) против нерекурсивной блокировки (мьютекс)
- locking Почему блокировка (это) {...} плохая?
- lookup Что быстрее, поиск по хэшу или бинарный поиск?
- lookup Функция с тем же именем, но другой подписью в производном классе
- lookup лучшие практики с кодом или таблицами поиска
- lookup Как я могу получить преобразование поиска SSIS, чтобы игнорировать алфавитный регистр?