HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

Dynamic Multithreading lock

Submitted by: @import:stackexchange-codereview··
0
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):

// 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 collection

Code 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 collection

Context

StackExchange Code Review Q#128583, answer score: 3

Revisions (0)

No revisions yet.