对于.NET 4.0 Beta 2,大家可能还处于试用阶段,本文将讨论的是.NET 4.0 Beta 2改进对协调数据结构类库,希望对大家有所帮助。
协调数据结构(Coordination Data Structures,CDS)被设计为在并发环境下使用的组件,它也可用于构建复杂的并发框架。此外,它还包含了高级的同步工具,如Barrier,多种线程安全的集合,以及多种构建Future模型的方式。
#T#
Barrier类的作用是在多个阶段的操作之间创建同步点。在使用之前,Barrier需要知道有多少线程将会使用它。每个线程达到检查点时,便要调用Barrier的SignalAndWait方法。这么做会引起阻塞,当所有线程都调用了这个方法后,便会同时释放所有线程。这个过程可以重复多次,每个这样的迭代都会增加其CurrentPhaseNumber属性。用于监控的代码可以随时检查正在使用Barrier的线程,以及还没有到达检查点的线程数量。CurrentPhaseNumber为Int64类型,因此每个Barrier可以支持多达9,223,372,036,854,775,807个阶段(之前的beta版本使用Int32,因此受限于40亿个阶段)。
BlockingCollection类用于生产者/消费者场景。它最简单的使用模式便是作为一个线程安全的队列,并且在队列为空时阻塞消费者。为了避免队列元素过多,你也可以为它设置一个最大值。在到达最大容量时,生产者便会被阻塞,直到某个消费者取出元素。当BlockingCollection填充完毕之后,生产者可以将其标记为完成。这样便无法添加更多的元素,同时也会释放了所有的消费者。
BlockingCollection并非只能单独使用,多个 BlockingCollection可以一起使用。在这种模式下,生产者和消费者可以指明为任意一个BlockingCollection添加或删除元素,而不在乎某个特定的集合。这么做可以充分在集合之间的实现某种负载均衡。
ConcurrentDictionary类支持原子性的添加和更新操作。为了实现这个功能,你需要向GetOrAdd及AddOrUpdate方法中传入一个委托。如果当前键不在集合中便会调用Add委托。如果键存在,那么便会返回对应的值,或是将其传递给Update委托。
原本还有计划实现一个并行链表,但是这点在beta 2中被取消了。Joshua Phillips写到,他们无法为这个类在性能和可用性之间做出平衡:
在每个软件专业人士的职业生涯中,总会遇到某些情况需要放弃他们所钟爱的东西。他们的发明虽然很棒,但总会有这样那样的原因,导致这些东西失去存在的充分价值。我知道你们对Beta 1中的ConcurrentLinkedList
对于需要延迟执行的函数,目前有了两个选择。如果你想使用future模型来传递那些只在需要时才调用的函数,那么可以使用Lazy类。这个类封装了一个函数,保证它只在第一次访问Value属性的时候才执行,以后对于Value属性的多次访问不会引起函数的重复调用。
第二个选项则是LazyInitializer模块。EnsureInitialized方法是一个保证初始化完成的轻量级做法,它在(且仅在)目标变量为null的情况才调用委托。这保证了目标变量只会设置一次。不过,如果没有使用同步对象的话,委托可能会被几个并发线程调用多次。