多线程-数据与控制同步
一,数据同步
CLR的数据同步包装简单到用c#用Lock关键字,vb.net用SyncLock围出一个临界域就好了。更细一步的话,提
供了读写锁类ReaderWriterLockSlim 类,这是在3.5后出现的类,用于取代1.1的ReaderWriterLock 类。
ReaderWriterLock直到2.0修复了部分问题但是还存在些问题,这里有篇很好的文章说明了读写锁。通过读写锁,不必什么都是独占
锁,共读提高性能。
二,控制同步
CLR提供了Monitor类,其有三个方法:
Wait(object obj);
Monitor.Pulse(object obj);
Monitor.PulseAll(object obj);
当前线程调用Monitor.Wait后,围绕obj建立的事件队列则添加一个通知对象。
Monitor.Pulse(object obj)采用先进先出原则,通知事件队列中的一个线程。
Monitor.PulseAll(object obj)遍历通知所有线程。
实现自己的线程池,或其他需要同步的场景一般都会用这个三个方法实现同步。
以下是个小实例,可以试着调试玩玩。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; namespace ControlSynTest { class Program { static int synValue = 0; static object synobj = new object(); static void Main(string[] args) { Thread thr1 = new Thread(new ThreadStart(Work1)); Thread thr2 = new Thread(new ThreadStart(Work2)); Thread thr3 = new Thread(new ThreadStart(Work3)); thr3.Start(); thr2.Start(); thr1.Start(); Console.Read(); } protected static void Work1() { lock (synobj) { while (synValue != 0) { Monitor.Wait(synobj); } synValue++; Monitor.PulseAll(synobj); Console.WriteLine("Work1:"+ synValue.ToString()); } } protected static void Work2() { lock (synobj) { while (synValue != 1) { Monitor.Wait(synobj); } synValue++; Monitor.Pulse(synobj); Console.WriteLine("Work2:" + synValue.ToString()); } } protected static void Work3() { lock (synobj) { while (synValue != 2) { Monitor.Wait(synobj); } synValue-=2; Monitor.Pulse(synobj); Console.WriteLine("Work3:" + synValue.ToString()); } } } }