patterncsharpMinor
Dynamic Multithreading lock
Viewed 0 times
multithreadinglockdynamic
Problem
I need to create an structure to control dynamically locks. For example, I have 100 threads running, and each thread will "process" a "key". Sometimes two threads could be processing the same "key", and if it occurs, a dynamic lock needs to be created and used by both, to process one at a time.
I create the following structure and I would like a code review, to find possible bugs (even if it is extremely rare):
I create the following structure and I would like a code review, to find possible bugs (even if it is extremely rare):
// This is the class who control to create one different lock for each key.
public class DynamicLockGenerator
{
private static Dictionary _locksByKeys = new Dictionary();
private static object _lock = new object();
public static objectGetLock(string key)
{
lock (_lock)
{
if (!_locksByKeys.ContainsKey(key))
_locksByKeys.Add(key, new object());
return _locksByKeys[key];
}
}
public static void RemoveLock(string key)
{
lock (_lock)
{
//This line is extremely important: One lock object can only be removed
//if no thread are using it.
if (Monitor.TryEnter(_locksByKeys[key]))
{
_locksByKeys.Remove(key);
}
}
}
}
//This is the use of the class. All threads do the same thing, but with different (or equal) keys.
object lockObj = DynamicLockGenerator.GetLock(key);
lock (lockObj)
{
//PROCESS THE KEY
}
DynamicLockGenerator.RemoveLock(key);Solution
I'm pretty sure you have the potential for a race condition if one thread releases the lock and removes it, after another thread has got the lock but not yet locked it.
Thread one GetLock(someKey) // Creates lock, returns dynamic key
Thread one Lock(dynamicKey)
Thread one complete processing (exits lock section)
Thread two GetLock(someKey) // returns existing key
Thread one RemoveLock // removes lock from collection (not yet being used)
Thread two Lock(dynamicKey) // Now we've locked an object no longer in collection
Thread two complete processing (exit lock block)
Thread two Remove lock // tries to remove a lock that's not in the collectionCode Snippets
Thread one GetLock(someKey) // Creates lock, returns dynamic key
Thread one Lock(dynamicKey)
Thread one complete processing (exits lock section)
Thread two GetLock(someKey) // returns existing key
Thread one RemoveLock // removes lock from collection (not yet being used)
Thread two Lock(dynamicKey) // Now we've locked an object no longer in collection
Thread two complete processing (exit lock block)
Thread two Remove lock // tries to remove a lock that's not in the collectionContext
StackExchange Code Review Q#128583, answer score: 3
Revisions (0)
No revisions yet.