ИИ для программиста?
Но это мелочь.
В этот раз без перевода
This code has a subtle thread safety issue. While using ConcurrentDictionary is a good start, there's a problem with how the lock object is created.
The new object()
is evaluated before GetOrAdd
is called, not as a factory method. This means that if two threads try to add the same key simultaneously, they could create two different lock objects. Even though ConcurrentDictionary will only store one of them, the other thread might get its own unique lock object, breaking the mutual exclusion.
---
Here's what can happen when two threads (T1 and T2) try to access the same key simultaneously:
- T1 reads key=1, evaluates
new object()
→ creates Object_A - T2 reads key=1, evaluates
new object()
→ creates Object_B - T1 calls GetOrAdd(1, Object_A)
- T2 calls GetOrAdd(1, Object_B)
Even though ConcurrentDictionary.GetOrAdd ensures only one value is stored (let's say Object_A wins), T2 still holds Object_B in its locker
variable.
// Thread 1
lock(Object_A) { ... } // Locks using object from dictionary
// Thread 2
lock(Object_B) { ... } // Locks using different object!
Now both threads can enter their critical sections simultaneously because they're locking on different objects!
Перейти на |