【发布时间】:2015-05-11 15:47:54
【问题描述】:
我已经实现了一个简单的任务来创建一个固定大小的列表,该列表允许并发写入,并且可以随时转储列表中项目的最新快照。
这是我的实现。每个线程的偏移量将自动增加,如果达到列表的大小,则重置。不同的线程应该对数组的每个部分具有独立的访问权限。
我的问题是当我调用 Dump() 时,前几个项目没有存储在列表中。另外,是否有一个可以同时进行原子增加和重置的互锁函数,所以我不必创建一个更衣室对象和一个锁块?谢谢。
public static void Main(string[] args)
{
ConcurrentCircularFixedList<int> list = new ConcurrentCircularFixedList<int>(20);
Enumerable.Range(1, 30).AsParallel().Select(nu => list.Enqueu(nu)).ToList();
}
public class ConcurrentCircularFixedList<T>
{
private int _size;
private int _offset;
private sealed object _locker = new Object();
privateT[] _list;
public ConcurrentCircularFixedList(int size)
{
_size = size;
_offset = 0;
_list = new T[_size];
}
public int Enqueu(T item)
{
_list[_offset] = item;
lock(_locker)
{
Debug.Write("B " + _offset);
_offset += 1;
if(_offset == _size)
_offset = 0;
Debug.Write("A " + _offset + "\n");
}
return _offset;
}
public T[] Dump()
{
return _list.ToArray();
}
}
【问题讨论】:
-
Dump上没有锁,但我不认为任何一个锁都是必要的。 -
我投票结束这个问题,因为它属于 CR。
-
@BrianRasmussen,你们很快,我误按了提交按钮。请查看我的问题。
-
@Aron,在我的 Dump 方法中,我调用了 ToArray(),它应该创建一个新数组,所以我认为不需要锁。
-
@Aron Sriram 展示的示例会抛出,原因是他给出的。他描述了一种可能的情况,在这种情况下,将使用数组边界之外的索引来调用索引器。更不用说物品掉在地板上或退回两次的可能性,使用此代码非常合理。
标签: c# list concurrency