基于ID字段的并发对象锁我有一个生产者/消费者进程。consume对象有一个ID属性(整数类型),我想一次只消费一个具有相同ID的对象。我怎样才能做到这一点?也许我可以做这样的事情,但我不喜欢它(创建太多对象而每天只使用一两个具有相同ID的对象并且锁定(_lockers)有点耗时:privatereadonlyDictionary_lockers=newDictionary();privateobjectGetLocker(intid){lock(_lockers){if(!_lockers.ContainsKey(id))_lockers.Add(id,newobject());return_lockers[id];}}privatevoidConsume(Tnotif){lock(GetLocker(notif.ID)){...}}entercodehere注意:同样的问题,ID属性是字符串类型(在cas中,我可以锁定string.Internal(currentObject.ID)按照建议在评论中,一种方法是使用固定锁池(比如32)并使用ID模32来确定要使用哪个锁。这可能会导致一些错误的锁共享。32是天上掉下来的数字-这个Will取决于你的ID值分布,消费者数量等。你能不能让你的ID对每个对象都是唯一的?如果是这样,你可以只对对象本身应用锁。首先,你有锁吗(_lockers)你确定那个lock(_lockers)确实是一个瓶颈?因为如果它没有坏,就不要修理它。编辑:我没有仔细阅读,这是关于创建的(大)辅助对象的数量。我认为Damien在这个Idea上有一个很好的想法,我将对这些字符串留下一些想法:关于注意:同样的问题,ID属性是字符串类型(在cas中,我可以锁定string.Internal(currentObject.ID)不,坏主意。你可以锁定A字符串,但你必须担心它们被拘留。很难确定它们是唯一的。我会将同步的FIFO队列视为所有生产对象的单独类/单例-生产者将对象入队,消费者出队-因此实际对象不再需要任何同步。然后在实际对象之外完成同步。如何从ID对象池中分配ID并锁定这些ID?创建项目时:varitem=CreateItem();IDid=IDPool.Instance.Get(id);//给对象分配iditem.ID=id;ID池创建并维护一个共享ID实例:classIDPool{privateDictionaryids=newDictionary();publicIDGet(intid){//从共享池中获取ID或在池中创建新实例。//alwaysreturnssameIDinstanceforgiveninteger}}然后锁定ID,它现在是你的Consume方法中的引用:privatevoidConsume(Tnotif){lock(notif.ID){...}}这不是最好的解决方案,它只是在不同的地方解决了问题——但如果你认为你对锁有压力,你可以通过这种方法获得性能提升(假设你的对象是在单个上创建的线程,则不需要同步ID池)。请参阅操作方法:同步生产者线程和消费者线程(C#编程指南)除了使用lock关键字简单地防止同时访问外,还有两个事件对象可提供进一步的同步。一个用于通知工作线程终止,另一个用于生产者线程在有新项目添加到队列时向消费者线程发出信号。这两个事件对象被封装在一个名为SyncEvents的类中。这允许将事件传递给代表消费者和生产者线程的对象。--编辑--我写的一个简单的代码片段;看看这是否有帮助。我认为这就是weismat所指的?-编辑-怎么样:创建一个对象,比如CCustomer将持有:将持有的字典现在当你检查以下内容时,上面是C#学习教程:基于ID字段的并发对象锁定所有关于共享,如果对每个人都有帮助有用和需要了解更多C#学习教程,希望大家多多关注——if(!_lockers.ContainsKey(id))_lockers.Add(id,newCCustomer(/**bInProgress=true**/));返回_lockers[id];**//在这里您可以检查bInProgress值并做出相应的响应**。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
