
这里给Barrier初始化的参与者数量是3,同时每完成一个步骤的时候会调用委托,该方法是输出count的值步骤索引。参与者数量后来增加了两个又减少了一个。每个参与者的操作都是相同,给count进行原子自增,自增完则调用SgnalAndWait告知Barrier当前步骤已完成并等待下一个步骤的开始。但是第三次由于回调方法里抛出了一个异常,每个参与者在调用SignalAndWait的时候都会抛出一个异常。通过Parallel开始了一个并行操作。假设并行开的作业数跟Barrier参与者数量不一样就会导致在SignalAndWait会有非预期的情况出现。
接下来说两个Attribute,这个估计不算是同步构造,但是也能在线程同步中发挥作用
MethodImplAttribute这个Attribute适用于方法的,当给定的参数是MethodImplOptions.Synchronized,它会对整个方法的方法体进行加锁,凡是调用这个方法的线程在没有获得锁的时候就会被阻塞,直到拥有锁的线程释放了才将其唤醒。对静态方法而言它就相当于把该类的类型对象给锁了,即lock(typeof(ClassType));对于实例方法他就相当于把该对象的实例给锁了,即lock(this)。最开始对它内部调用了lock这个结论存在猜疑,于是用IL编译了一下,发现方法体的代码没啥异样,查看了一些源码也好无头绪,后来发现它的IL方法头跟普通的方法有区别,多了一个synchronized

于是网上找各种资料,最后发现"junchu25"的博客[1][2]里提到用WinDbg来查看JIT生成的代码。
调用Attribute的

调用lock的

对于用这个Attribute实现的线程同步连Jeffrey都不推荐使用。
System.Runtime.Remoting.Contexts.SynchronizationAttribute这个Attribute适用于类,在类的定义中加了这个Attribute并继承与ContextBoundOject的类,它会对类中的所有方法都加上同一个锁,对比MethodImplAttribute它的范围更广,当一个线程调用此类的任何方法时,如果没有获得锁,那么该线程就会被阻塞。有个说法是它本质上调用了lock,对于这个说法的求证就更不容易,国内的资源少之又少,里面又涉及到AppDomain,线程上下文,最后核心的就是由SynchronizedServerContextSink这个类去实现的。AppDomain应该要另立篇进行介绍。但是在这里也要稍微说一下,以前以为内存中就是有线程栈与堆内存,而这只是很基本的划分,堆内存还会划分成若干个AppDomain,在每个AppDomain中也至少有一个上下文,每个对象都会从属与一个AppDomain里面的一个上下文中。跨AppDomain的对象是不能直接访问的,要么进行按值封送(相当于深复制一个对象到调用的AppDomain),要么就按引用封送。对于按引用封送则需要该类继承MarshalByRefObject。对继承了这个类的对象进行调用时都不是调用类的本身,而是通过代理的形式进行调用。那么跨上下文的也需要进行按值封送操作。平常构造的一个对象都是在进程默认AppDomain下的默认上下文中,而使用了SynchronizationAttribute特性的类它的实例是属于另外的一个上下文中,继承了ContextBoundObject基类的类进行跨上下文访问对象时也是通过按引用封送的方式用代理访问对象,并非访问到对象本身。至于是否跨上下文访问对象可以通过的RemotingServices.IsObjectOutOfContext(obj)方法进行判断。SynchronizedServerContextSink是mscorlib的一个内部类。当线程调用跨上下文的对象时,这个调用会被SynchronizedServerContextSink封装成WorkItem的对象,该对象也mscorlib的中的一个内部类,SynchronizedServerContextSink就请求SynchronizationAttribute,Attribute根据现在是否有多个WorkItem的执行请求来决定当前处理的这个WorkItem会马上执行还是放到一个先进先出的WorkItem队列中按顺序执行,这个队列是SynchronizationAttribute的一个成员,队列成员入队出队时或者Attribute判断是否马上执行WorkItem时都需要获取一个lock的锁,被锁的对象也正是这个WorkItem的队列。这里面涉及到几个类的交互,鄙人现在还没完全看清,以上这个处理过程可能有错,待分析清楚再进行补充。不过通过这个Attribute实现的线程同步按逼人的直觉也是不推荐使用的,主要是性能方面的损耗,锁的范围也比较大。










