一.ManualResetEvent
1.WaitOne
阻止当前线程,直到当前 System.Threading.WaitHandle 收到信号。
2.Set
将事件状态设置为终止状态,允许一个或多个等待线程继续。
3.ReSet
将事件状态设置为非终止状态,导致线程阻止。
class Program { static ManualResetEvent _mre = new ManualResetEvent(true); static void Main(string[] args) { Thread[] _threads = new Thread[3]; for (int i = 0; i < _threads.Count(); i++) { _threads[i] = new Thread(ThreadRun); _threads[i].Start(); } } static void ThreadRun() { int _threadID = 0; while (true) { _mre.WaitOne(); _threadID = Thread.CurrentThread.ManagedThreadId; Console.WriteLine("current Tread is " + _threadID); Thread.Sleep(TimeSpan.FromSeconds(2)); } } }
static ManualResetEvent _mre = new ManualResetEvent(true);运行结果
static ManualResetEvent _mre = new ManualResetEvent(false);运行结果
终止状态时WaitOne()允许线程访问下边的语句
非终止状态时WaitOne()阻塞线程,不允许线程访问下边的语句
二.AutoResetEvent
AutoResetEvent和ManualResetEvent的区别是
ManualResetEvent 运行set()后,底下所有的waitOne()都可以执行
AutoResetEvent 运行set()后,底下其中之一的waitOne()都可以执行
三.Semaphore
这玩意是.net 4.0新增的,用于控制线程的访问数量,默认的构造函数为initialCount和maximumCount,表示默认设置的信号量个数和
最大信号量个数,其实说到底,里面是采用计数器来来分配信号量,当你WaitOne的时候,信号量自减,当Release的时候,信号量自增,然而
当信号量为0的时候,后续的线程就不能拿到WaitOne了,所以必须等待先前的线程通过Release来释放。
class Program { static void Main(string[] args) { Thread t1 = new Thread(Run1); t1.Start(); Thread t2 = new Thread(Run2); t2.Start(); Console.Read(); } static Semaphore sem = new Semaphore(1, 10); static void Run1() { //默认的信号量个数为1,所以t2想执行必须等待t1通过Release来释放 sem.WaitOne(); Console.WriteLine("大家好,我是Run1"); sem.Release(); } static void Run2() { sem.WaitOne(); Console.WriteLine("大家好,我是Run2"); sem.Release(); } }