Блокировка lock в C#
Когда несколько потоков изменяют одну структуру данных, без правил доступа обновления теряются или списки повреждаются. Блокировка гарантирует, что критическая секция выполняется только одним потоком в момент времени.
В C# оператор lock компилируется в вход и выход из монитора объекта-синхронизатора. Объект не обязан «хранить» данные - достаточно стабильной ссылки, по которой все потоки договорились ждать.
Несколько потоков будут по очереди дописывать номера заказов в общий журнал. Все три потока успели AppendOrder под одной блокировкой; без lock Count часто был бы меньше:
List<string> journal = new();
object gate = new();
void AppendOrder(int id)
{
lock (gate)
{
journal.Add($"ord-{id}");
}
}
Thread[] workers =
[
new(() => AppendOrder(1)),
new(() => AppendOrder(2)),
new(() => AppendOrder(3)),
];
foreach (Thread t in workers) t.Start();
foreach (Thread t in workers) t.Join();
Console.WriteLine(journal.Count); // выведет 3
Четыре потока параллельно добавляют в общий список доставок строки "ship-1", "ship-2", "ship-3" и "ship-4". Защитите список и выведите итоговое число элементов.