Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I use dictionary elements as lock objects?

I have multiple queues that are being accessed by multiple threads. To achieve thread-safety, I did the following:

private static Dictionary<string, Queue<string>> MyQueues = new Dictionary<string, Queue<string>>();

public static string GetNextQueueElementForKey(string key)
{
    string res = string.Empty;

    if (MyQueues.Keys.Contains(key))
    { 
       Queue<string> queue = MyQueues[key];
       lock (queue)
       {
           if (queue.Count() > 0)
           {
               res = queue.Dequeue();
           }
       }
   }

   return res;
}

I could also lock MyQueues, but then I would lock more than necessary. So my question is, if locking an object contained in a dictionary is going to work - assuming that a key's value (the queue) is never changed.

like image 553
Ben Avatar asked Jun 07 '13 12:06

Ben


1 Answers

You can - but I generally wouldn't. Personally I usually attempt to lock on plain System.Object instances which aren't used for anything else, and ideally aren't even exposed to any code other than the class locking on them. That way you can be absolutely sure that nothing else is going to lock.

In this case it looks like you've got control over the queues so you know they won't be used by other code, but it's possible that the code inside Queue<T> will lock on this. That's probably not the case, but it's the kind of thing I would worry about.

Fundamentally, I wish that .NET hadn't taken Java's approach of "a monitor for every object" - I wish Monitor had been an instantiable class.

(I assume you're only actually reading from the dictionary from multiple threads? It's not safe to use dictionaries for multi-threaded read/write.)

like image 129
Jon Skeet Avatar answered Sep 19 '22 22:09

Jon Skeet