线程同步-AutoResetEvent
线程同步的其他方式:
1、AutoResetEvent
使用WaitOne和set 进行阻塞和释放阻塞的线程,
WaitOne方法定义:
public virtual bool WaitOne(int millisecondsTimeout);该方法用来阻塞线程,当在指定的时间间隔还没有收到一个信号时,将返回false。
public AutoResetEvent(bool initialState); 当initialState值为false时线程阻塞等待set信号或者等待超时时间结束,当为true时不进行线程阻塞。
millisecondsTimeout 为超时时间 当设置的超时时间到时 无论是否收到了set的信号 线程将解除阻塞的状态立即执行 WaitOne的返回值为false 当收到set的信号解除线程阻塞时返回值为true。
例子:
using System; using System.Threading; namespace KenelMode { class Program { // 初始化自动重置事件,并把状态设置为非终止状态 // 如果这里把初始状态设置为True时, // 当调用WaitOne方法时就不会阻塞线程,看到的输出结果的时间就是一样的了 // 因为设置为True时,表示此时已经为终止状态了。 public static AutoResetEvent autoEvent = new AutoResetEvent(false); static void Main(string[] args) { Console.WriteLine("Main Thread Start run at: " +DateTime.Now.ToLongTimeString()); Thread t = new Thread(TestMethod); t.Start(); // 阻塞主线程1秒后 // 调用 Set方法释放线程,使线程t可以运行 Thread.Sleep(3000); // Set 方法就是把事件状态设置为终止状态。 autoEvent.Set(); Console.Read(); } public static void TestMethod() { if (autoEvent.WaitOne(2000)) { Console.WriteLine("Get Singal to Work"); // 3秒后线程可以运行,所以此时显示的时间应该和主线程显示的时间相差一秒 Console.WriteLine("Method Restart run at: " + DateTime.Now.ToLongTimeString()); } else { Console.WriteLine("Time Out to work"); Console.WriteLine("Method Restart run at: " + DateTime.Now.ToLongTimeString()); } } } }
2、信号量(Semaphore)
信号量(Semaphore)是由内核对象维护的int变量,当信号量为0时,在信号量上等待的线程会堵塞,信号量大于0时,就解除堵塞。当在一个信号量上等待的线程解除堵塞时,内核自动会将信号量的计数减1。在.net 下通过Semaphore类来实现信号量同步。
Semaphore类限制可同时访问某一资源或资源池的线程数。线程通过调用 WaitOne方法将信号量减1,并通过调用 Release方法把信号量加1
class Program { // 初始信号量计数为0,最大计数为10 public static Semaphore semaphore =new Semaphore(0,10); public static int time = 0; static void Main(string[] args) { for (int i = 0; i < 5; i++) { Thread test = new Thread(new ParameterizedThreadStart(TestMethod)); // 开始线程,并传递参数 test.Start(i); } // 等待1秒让所有线程开始并阻塞在信号量上 Thread.Sleep(500); // 信号量计数加4 // 最后可以看到输出结果次数为4次 semaphore.Release(4); Console.Read(); } public static void TestMethod(object number) { // 设置一个时间间隔让输出有顺序 int span = Interlocked.Add(ref time, 100); Thread.Sleep(1000 + span); //信号量计数减1 semaphore.WaitOne(); Console.WriteLine("Thread {0} run ", number); } }
3、 Mutex 使用Mutex.WaitOne()和Mutex.ReleaseMutex();