Привет. Искал инфу про потокобезопасную коллекцию и почти везде такой код:
Добавление в коллекцию
public void Add(int value)
{
lock(sync)
{
Add(value);
}
}
тут sync это
private object sync = new object();
Я вставил себе.
public void Add(TkeyId keyId, TkeyName keyName, Tvalue value)
{
lock(sync)
{
if (this.Where(g => g.Key.Name.Equals(keyName) && g.Key.Id.Equals(keyId)).Count() > 0)
return;
this.Add(new UserKey<TkeyId, TkeyName>(keyId, keyName), value);
}
}
Так вот вопрос в чем прикол.Как он блокирует за счет чего. Простым языком объясните
Конструкция lock
гарантирует следующее: два блока
lock (p)
{
// тут содержимое блока
}
бегущие в разных потоках, никогда не будут выполнены одновременно, если объект p
один и тот же.* Если один поток находится внутри lock
, то другой будет ждать окончания выполнения этого блока. В этом и состоит суть блокировки.
Как именно технически это реализуется, не так уж и важно. В C# lock
вызывает конструкцию Monitor.Enter
, а она, в свою очередь, внутри кода BCL реализует функциональность, подобную CRITICAL_SECTION
самостоятельно, используя короткий холостой цикл (spin wait) и системные примитивы синхронизации. На других системах, разумеется, используются другие синхронизационные функции ОС. Как именно работают эти функции — внутренняя подробность устройства ОС (завязанная, надо думать, на системный планировщик потоков).
Главное — знать, что внутрь lock
'а на один и тот же объект два потока проникнуть не могут.
*Также она гарантирует нужные memory barrier'ы для многопоточного сценария, но это неважно в контексте данного обсуждения.
Оператор lock (sync) { ... }
будет транслирован в следующую конструкцию (.NET >= 4):
// Флаг успешной блокировки
bool acquiredLock = false;
try
{
// Захватываем блокировку для sync
Monitor.Enter(lockObject, ref acquiredLock);
// Потокобезопасный код
}
finally
{
// Освобождаем блокировку для sync если блокировка была выполнена
if (acquiredLock)
{
Monitor.Exit(lockObject);
}
}
Когда потоком вызывается метод Monitor.Enter
то участок кода будет заблокирован для доступа других потоков, вплоть до того момента, когда поток не вызовет метод Monitor.Exit
.
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
ASP занимаюсь недавно поэтому прошу сильно не битьЕсть небольшое приложение на asp MVC в котором нужно вывести на страничку некоторый список
Есть 3 лэйблы, 2 из который надо скрытьДелаю это не через XAML, почему не спрашивайте
После 20 секунд (примерно) от подключения бота к канал, он из него выходит, с сообщением: "Время ожидания операции истекло"