使用EventWaitHandle实现线程同步例子
本篇通过一个列子使用EventWaitHandle实现两个线程的同步。请参看下面的列子。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; namespace ThreadSynDemo { class Program { private int n1, n2, n3; static void Main(string[] args) { Program p = new Program(); Thread t0 = new Thread(new ThreadStart(p.WriteThread)); Thread t1=new Thread(new ThreadStart(p.ReadThread)); t0.Start(); t1.Start(); Console.ReadLine(); } private void WriteThread() { Console.WriteLine("WriteThread"); n1 = 1; n2 = 2; n3 = 3; } //有时结果为0+0+0=0;有时结果为1+2+3=6;因为线程执行循序是不确定性导致。 //我们需要结果始终是1+2+3=6;这个需要保证WriteThread()比ReadThread()早执行。这个就涉及到线程的同步问题。 private void ReadThread() { Console.WriteLine("{0}+{1}+{2}={3}",n1,n2,n3,n1+n2+n3); } } }
上面的列子有时结果为0+0+0=0;有时结果为1+2+3=6;因为线程执行循序是不确定性导致。 我们需要结果始终是1+2+3=6;这个需要保证WriteThread()比ReadThread()早执行。这个就涉及到线程的同步问题。
下面我们就用EventWaitHandle实现这两个线程的同步。请看下面的列子
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; //下面我们使用EventWaitHandle类实现线程的同步 //EventWaitHandle类:能让操作系统通过发出的信号完成多个线程之间的同步,需要同步的线程可以阻塞当前线程。 // 然后根据Windows操作系统发出的信号,决定阻塞等待其他工作完成,,还是不再等待而直接继续执行 //EventWaitHandle类方法如下: //(1)Reset将信号的状态置为非终止状态(不让操作系统发出信号),从而导致那些只有收到信号才能继续执行的线程处于阻塞状态 //(2)Set:将事件状态置为非终止状态,这样等待的线程会收到信号,从而有等待转为继续执行 //(3)WaitOne方法:阻塞当前线程,等待操作系统为其发出信号,直到收到信号才解除阻塞 //操作系统发出信号的两种方式: //(1)发一个信号,使某个等待信号的线程解除阻塞,继续执行.自动重置(AutoResetEvent) //(2)发一个信号,使所有等待信号的线程全部解除阻塞,继续执行.手动重置(ManualRestEvent) namespace ThreadAsyDemo2 { class Program { private int n1, n2, n3; //将信号状态设置为非终止状态,使用手动重置 EventWaitHandle myEventWaitHandle = new EventWaitHandle(false, EventResetMode.ManualReset); static void Main(string[] args) { Program p = new Program(); Thread t0 = new Thread(new ThreadStart(p.WriteThread)); Thread t1 = new Thread(new ThreadStart(p.ReadThread)); t0.Start(); t1.Start(); Console.ReadLine(); } private void WriteThread() { //允许其他需要等待的线程阻塞 myEventWaitHandle.Reset(); Console.WriteLine("WriteThread"); n1 = 1; n2 = 2; n3 = 3; //允许其他等待的线程继续 myEventWaitHandle.Set(); } //有时结果为0+0+0=0;有时结果为1+2+3=6;因为线程执行循序是不确定性导致。 //我们需要结果始终是1+2+3=6;这个需要保证WriteThread()比ReadThread()早执行。这个就涉及到线程的同步问题。 private void ReadThread() { //阻塞当前线程,直到收到信号 myEventWaitHandle.WaitOne(); Console.WriteLine("{0}+{1}+{2}={3}", n1, n2, n3, n1 + n2 + n3); } } }