I'm looking for someone to verify my understanding of concurrency and memory model in this situation of code.
public static class ExampleClass
{
private static ConcurrentDictionary<int, TimeSpan> DeviceThrottles { get; set; } = new ConcurrentDictionary<int, TimeSpan>();
public static void ExampleFunction(int deviceId)
{
TimeSpan timedelay = DeviceThrottles[deviceId];
if (timedelay.Seconds < 10)
{
DeviceThrottles[deviceId] = new TimeSpan(days: 0, hours: 0, minutes: 0, seconds: 10);
}
}
}
The application has multiple threads running that can call ExampleFunction
. Given the following situation.
Thread 1 calls ExampleFunction(1)
and timedelay
was only 5 seconds, so DeviceThrottles[deviceId]
is set to a new TimeSpan of 10 seconds.
A short time later, Thread 2 calls ExampleFunction(1)
. Is it possible that the local thread cache could still have the timedelay
of only 5 seconds? My understanding is that ConcurrentDictionary
's purpose is just thread-safety of a collection, not maintaining the most up to date memory of objects across threads.
If my understanding is correct, should the code to be modified to the following to ensure the TimeSpan
value is up-to-date across threads.
public static void ExampleFunction(int deviceId)
{
lock (lockObj)
{
TimeSpan timedelay = DeviceThrottles[deviceId];
if (timedelay.Seconds < 10)
{
DeviceThrottles[deviceId] = new TimeSpan(days: 0, hours: 0, minutes: 0, seconds: 10);
}
}
}
With the lock, it seems like the concurrent dictionary loses its appeal.