我可以使用字典元素作为锁定对象吗?

Ben*_*Ben 6 c# multithreading locking

我有多个队列正在被多个线程访问.为了实现线程安全,我做了以下事情:

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;
}
Run Code Online (Sandbox Code Playgroud)

我也可以锁定MyQueues,但是我会锁定不必要的东西.所以我的问题是,如果锁定字典中包含的对象将起作用 - 假设一个键的值(队列)永远不会改变.

Jon*_*eet 7

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.)