Csharp/C#教程:没有锁的Threadsafe集合分享


没有锁的Threadsafe集合

我正准备接受采访,我遇到了这个问题。 我试过,但我找不到任何可以创建包含线程安全集合而没有“锁定”的类。 如果知道任何解决方案,请帮助。

创建一个派生自Object的C#类,并实现以下方法:

要求:

这是一种通过处理本地副本然后尝试在检查比赛时与全局集合进行primefaces交换来实现对集合的无锁修改的方法:

 public class NonLockingCollection { private List collection; public NonLockingCollection() { // Initialize global collection through a volatile write. Interlocked.CompareExchange(ref collection, new List(), null); } public void AddString(string s) { while (true) { // Volatile read of global collection. var original = Interlocked.CompareExchange(ref collection, null, null); // Add new string to a local copy. var copy = original.ToList(); copy.Add(s); // Swap local copy with global collection, // unless outraced by another thread. var result = Interlocked.CompareExchange(ref collection, copy, original); if (result == original) break; } } public override string ToString() { // Volatile read of global collection. var original = Interlocked.CompareExchange(ref collection, null, null); // Since content of global collection will never be modified, // we may read it directly. return string.Join(",", original); } } 

编辑 :由于使用Interlocked.CompareExchange来隐式执行易失性读写会引起一些混乱,我在Thread.MemoryBarrier调用的等效代码下面发布。

 public class NonLockingCollection { private List collection; public NonLockingCollection() { // Initialize global collection through a volatile write. collection = new List(); Thread.MemoryBarrier(); } public void AddString(string s) { while (true) { // Fresh volatile read of global collection. Thread.MemoryBarrier(); var original = collection; Thread.MemoryBarrier(); // Add new string to a local copy. var copy = original.ToList(); copy.Add(s); // Swap local copy with global collection, // unless outraced by another thread. var result = Interlocked.CompareExchange(ref collection, copy, original); if (result == original) break; } } public override string ToString() { // Fresh volatile read of global collection. Thread.MemoryBarrier(); var original = collection; Thread.MemoryBarrier(); // Since content of global collection will never be modified, // we may read it directly. return string.Join(",", original); } } 

您可以创建非阻止链接列表。 例如像这样的东西。

.net框架提供了像CompareExchange(Object, Object, Object)这样的方法CompareExchange(Object, Object, Object)它们允许您在不锁定整个列表的情况下编写安全代码。

基于这个问题,您应该能够在对象中添加并发集合,以便为您处理线程安全要求。 他们没有指定要使用的内部集合类型。

您应该能够从concurrentcollection命名空间实现其中一个集合并实现此目的。

http://msdn.microsoft.com/en-us/library/system.collections.concurrent.aspx

我的解决方案 基本上使用Interlocked.Exchange和AutoResetEvents模仿锁定。 做了一些简单的测试,似乎有效。

  public class SharedStringClass { private static readonly int TRUE = 1; private static readonly int FALSE = 0; private static int allowEntry; private static AutoResetEvent autoResetEvent; private IList internalCollection; public SharedStringClass() { internalCollection = new List(); autoResetEvent = new AutoResetEvent(false); allowEntry = TRUE; } public void AddString(string strToAdd) { CheckAllowEntry(); internalCollection.Add(strToAdd); // set allowEntry to TRUE atomically Interlocked.Exchange(ref allowEntry, TRUE); autoResetEvent.Set(); } public string ToString() { CheckAllowEntry(); // access the shared resource string result = string.Join(",", internalCollection); // set allowEntry to TRUE atomically Interlocked.Exchange(ref allowEntry, TRUE); autoResetEvent.Set(); return result; } private void CheckAllowEntry() { while (true) { // compare allowEntry with TRUE, if it is, set it to FALSE (these are done atomically!!) if (Interlocked.CompareExchange(ref allowEntry, FALSE, TRUE) == FALSE) { autoResetEvent.WaitOne(); } else { break; } } } } 

最简单的解决方案是使用string[]类型的字段。 每当调用者想要添加字符串时,创建一个新数组,并附加新项目并将其交换为旧数组。

此模型不需要同步。 它不能容忍并发写入器,但它允许并发读取。

上述就是C#学习教程:没有锁的Threadsafe集合分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请点击右边联系管理员删除。

如若转载,请注明出处:https://www.ctvol.com/cdevelopment/1015796.html

(0)
上一篇 2021年12月31日
下一篇 2021年12月31日

精彩推荐