tgoop.com/csharp_gepard/104
Create:
Last Update:
Last Update:
ConcurrentDictionary #собес #память
Коллеги, задачка. Прямо с собеса, с пылу-с-жару. Сколько раз значение будет выведено в консоль?
const string Key = "SomeKey";
var topLevel = new ConcurrentDictionary<string, string>();
for (var i = 1; i < 100; i++) {
var thread = new Thread(Add);
thread.Start(topLevel);
}
static void Add(object? val) {
var dict = (ConcurrentDictionary<string, string>)val!;
dict.GetOrAdd(Key, x => {
lock (Lock.Obj)
{
if (dict.TryGetValue(Key, out var value)) return value;
var res = Guid.NewGuid().ToString();
Console.WriteLine(res);
return res;
}
});
}
Усложняем:
1. Теперь заменим тип значения у
ConcurrentDictionary
на Guid
. Естественно строку var res = Guid.NewGuid().ToString();
нужно исправить как var res = Guid.NewGuid()
.2. А теперь изменим тип значения на
int
.Как же так? Надо пояснить в чём, собственно, дело. Можно скопировать и воспроизвести у себя. И я настоятельно (!) рекомендую это сделать.
---
С одной стороны, суть происходящего проста: ConcurrentDictionary не гарантирует, что элемент по ключу будет создан один и только один раз. Это делается для исключения проблем, которые могут возникнуть при выполнении неизвестного кода под блокировкой, что верно заметил коллега.
А другой стороны, суть происходящего в сложном сценарии не так проста, но всё ещё, кстати, логична.
Когда мы отпускаем
lock
, то железке нужно время записать данные в память. И чем бОльший объем данных мы записываем в память, тем это дольше, что подтверждает эмпирический опыт коллеги и дальнейшее развитие рассуждений.Причём скорость зависит (c) от всего сразу: размера данных, количества процессоров, разрядности процессора и скорости памяти. Например, размер
int
это 4, а string
- 8. И, если повезёт, это, в свою очередь, равно sizeof(IntPtr)
или nint
(в зависимости от разрядности процессора). Если разрядность позволяет записать данные в память за одну операцию, то это дает другим потокам (ядрам) больше времени посоревноваться на скорость. Если поток всего один - то конкуренции нет.Мораль всего этого такова:
BY C# Heppard
Share with your friend now:
tgoop.com/csharp_gepard/104