许多读者,一位作家 – 是否有可能避免锁定?
假设你有一个内存中的字符串列表,以及一个multithreading系统,有许多读者但只有一个编写器线程。
一般来说,是否可以在C#中实现这种系统而不使用锁? 实现是否会对线程如何交互做出任何假设(或者对它们可以做什么进行限制,何时)?
是。 诀窍是确保列表保持不变。 编写器将对主集合进行快照,修改快照,然后将快照发布到包含对主集合的引用的变量。 以下示例演示了这一点。
public class Example { // This is the immutable master collection. volatile List collection = new List (); void Writer() { var copy = new List (collection); // Snapshot the collection. copy.Add("hello world"); // Modify the snapshot. collection = copy; // Publish the snapshot. } void Reader() { List local = collection; // Acquire a local reference for safe reading. if (local.Count > 0) { DoSomething(local[0]); } } }
这种方法有几点需要注意。
由于上述限制,这将使您受益的情况非常有限。 最大的问题是写入首先要求完整拷贝,因此它们可能很慢。 但是,如果写入很少,那么这可能是可以忍受的。
我在这里的答案中描述了更多的模式,包括对多个作者来说安全的模式。
为避免锁定,您可能需要考虑Microsoft的并发集合 。 这些集合提供了对有序和无序表单中对象集合的线程安全访问。 他们使用一些巧妙的技巧来避免在尽可能多的实例内部锁定 。
对于线程库来说,这是一个相当普遍的请求 – 这种锁通常被称为“读写器锁”,或者是该主题的一些变体。 我没有必要专门使用C#实现,但有一个: http : //msdn.microsoft.com/en-us/library/system.threading.readerwriterlockslim.aspx
当然,你遇到的问题是,如果读者总是在阅读,你将永远无法让作家写作。 我相信你必须自己处理。
(好吧,所以它在技术上仍然是一个“锁定”,但它不是C#“锁定”构造,它是一个专门针对问题中所述目的而设计的更复杂的对象。所以我猜它是否是一个正确的答案在某种程度上取决于语义和他为什么问这个问题。)
您还可以使用Microsoft的新Immutable Collections库: http : //blogs.msdn.com/b/bclteam/archive/2012/12/18/preview-of-immutable-collections-released-on-nuget.aspx
注意:这与Concurrent Collections完全分开。
如果编写器仅在头部或尾部插入/删除,则可以使用单链接列表方法而无需锁定。 在任何一种情况下,如果事先构造新节点,则只需要一个primefaces操作(head = newHead;或tail.next = newTail)即可使读取操作可见。
在性能方面,插入和删除是O(1),而长度计算是O(n)。
上述就是C#学习教程:许多读者,一位作家 – 是否有可能避免锁定?分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/1251183.html