Привет. Искал инфу про потокобезопасную коллекцию и почти везде такой код:
Добавление в коллекцию
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.
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости