我有一个生产者/消费者进程。消费的对象有一个ID属性(整型),我希望一次只消费一个具有相同ID的对象。我该如何执行此操作?
也许我可以做这样的事情,但我不喜欢这样(创建了太多的对象,而每天只能使用一两个具有相同ID的对象,并且锁(_lockers)有点耗时:
private readonly Dictionary<int,object> _lockers = new Dictionary<int,object>();
private object GetLocker(int id)
{
lock(_lockers)
{
if(!_lockers.ContainsKey(id))
_lockers.Add(id,new object());
return _lockers[id];
}
}
private void Consume(T notif)
{
lock(GetLocker(notif.ID))
{
...
}
}
enter code here注意:同样的问题是ID属性是字符串类型的(在这种情况下,也许我可以锁定string.Internal(currentObject.ID) )
发布于 2009-12-09 18:26:53
正如注释中所指出的,一种方法是拥有一个固定的锁池(比如32个),并取ID模32来确定要采用哪个锁。这将导致某些锁的错误共享。32是从空气中挑选的数字-它将取决于您的ID值分布,有多少消费者,等等。
发布于 2009-12-09 18:14:25
你能让你的ID对每个对象都是唯一的吗?如果是这样,您可以只对对象本身应用一个锁。
发布于 2009-12-09 18:31:29
请参阅How to: Synchronize a Producer and a Consumer Thread (C# Programming Guide)
除了简单地防止使用lock关键字同时访问之外,还由两个事件对象提供进一步的同步。一个用于通知工作线程终止,另一个用于生产者线程在新项添加到队列时通知使用者线程。这两个事件对象封装在一个名为SyncEvents的类中。这样就可以轻松地将事件传递给表示消费者线程和生产者线程的对象。
-编辑--
这是我以前写的一个simple code snippet;看看这是否有帮助。我想这就是weismat所指向的?
-编辑--
下面的内容如何:
- An object of type object
- And a bool - for instance, bool bInProgress
包含的
现在,当您检查以下内容时
if(!_lockers.ContainsKey(id))
_lockers.Add(id,new CCustomer(/**bInProgress=true**/));
return _lockers[id]; **//here you can check the bInProgress value and respond accordingly**.https://stackoverflow.com/questions/1872866
复制相似问题