May*_*yur 14 c# collections multithreading
我正准备接受采访,我遇到了跟随问题.我试过,但我找不到任何可以创建包含线程安全集合而没有"锁定"的类.如果知道任何解决方案,请帮助.
创建一个派生自Object的C#类,并实现以下方法:
要求:
Dou*_*las 11
这是一种通过处理本地副本然后尝试在检查比赛时与全局集合进行原子交换来实现对集合的无锁修改的方法:
public class NonLockingCollection
{
private List<string> collection;
public NonLockingCollection()
{
// Initialize global collection through a volatile write.
Interlocked.CompareExchange(ref collection, new List<string>(), 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);
}
}
Run Code Online (Sandbox Code Playgroud)
编辑:由于使用Interlocked.CompareExchange隐式执行易失性读写引起了一些混乱,我在Thread.MemoryBarrier调用等效代码下面发布.
public class NonLockingCollection
{
private List<string> collection;
public NonLockingCollection()
{
// Initialize global collection through a volatile write.
collection = new List<string>();
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);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
8308 次 |
| 最近记录: |