Исходный код вики ConcurrentDictionary

Версия 11.1 от Alexandr Fokin на 2022/01/03 15:31

Последние авторы
1
2
3 **Описание работы метода AddOrUpdate**:
4 В dictionary есть одно значение по ключу key1 - val1.
5
6 1) Поток th1 запускает Update делегат по ключу key1. (Фиксирует текущее значение th1_v)
7 2) Поток th2 запускает Update делегат по ключу key1. (Фиксирует текущее значение th2_v)
8 3) Поток th2 заканчивает выполнение делегата Update. th1 сравнивает val1 = th2_v (Через equils).
9 Значение равны и th2 сохраняет результат.
10 4) Поток th1 заканчивает выполнение делегата Update. th2 сравнивает val1 = th1_v (Через equils).
11 Значение НЕ равны и th2 повторно вызывает Update делегат.
12 (Если элемент был удален, то запустить делегат Add)
13 !Повторного вызова делегата не произойдет, в случает если результат работы th2 эквивалентен исходному начальному значению val1.
14
15 Получается, что ни вызов AddOrUpdate, ни вызов конкретного делегата (Add/Update) сам по себе не блокирует значение в коллекции и не препятствует в изменении другими потокам.
16
17 По сути мы получаем **оптимистичную блокировку**. В случае неудачи которой, повторно вызывается действие обработки (add/update) для измененного значения по указанному ключу.
18 Критерием сравнения блокировки является Equils. В таком случае возможно имеет смысл перегрузка Equils и наличии в сущности некоторого ключевого поля. Нечто вроде Change Version TimeStamp.