在.Net中的各个线程之间同步对象集合的最佳方法是什么?

时间:2020-03-06 14:22:17  来源:igfitidea点击:

在.Net中的各个线程之间同步对象集合的最佳方法是什么?

我需要在trhead安全模式下从不同线程访问列表或者字典。带有添加,删除,Foreach等

解决方案

我们可以实现无锁队列:

http://www.boyet.com/Articles/LockfreeQueue.html

或者使用锁自己处理同步:

http://www.albahari.com/threading/part2.html#_Locking

Hashtable.Synchronized方法为Hashtable返回一个同步的(线程安全的)包装器。

http://msdn.microsoft.com/zh-cn/library/system.collections.hashtable.synchronized(VS.80).aspx

其他集合也存在此问题。

.Net中的许多收集类都内置了对多个线程进行同步并使它们安全访问的支持。例如(在C ++ / CLR中):

Collections::Queue ^unsafe_queue = gcnew Collections::Queue();
    Collections::Queue ^safe_queue = Collections::Queue::Synchronized(unsafe_queue);

我们可以丢弃对unsafe_queue的引用,并保留对safe_queue的引用。它可以在线程之间共享,并且可以保证线程安全访问。其他集合类(如ArrayList和Hashtable)也以类似的方式支持此功能。

在不了解细节的情况下,我倾向于委托和事件来通知更改。

http://msdn.microsoft.com/zh-CN/library/17sde2xt(VS.71).aspx

并实现观察者或者发布订阅模式

http://en.wikipedia.org/wiki/Observer_pattern
http://msdn.microsoft.com/en-us/library/ms978603.aspx

基本上,这取决于我们需要使用的模式。
如果有多个线程在同一位置读写,则可以使用与具有锁/监视器或者ReaderWriterLock的单个线程(可使用的数组,数组等)相同的数据结构,以防止出现竞争情况。
如果需要在线程之间传递数据,则需要某种队列(同步或者无锁),A组的线程将插入该队列,而B组的线程将出队。我们可能要使用WaitEvent(自动重置或者手动),以便在队列为空时不会丢失CPU。
这实际上取决于我们要实现哪种工作流程。