System.Diagnostics.Stopwatch watch = System.Diagnostics.Stopwatch.StartNew(); Thread myThread = new Thread(() => { Thread.Sleep(1000); result = 100; tellMe.Set(); }); myThread.Start(); tellMe.WaitOne(); Console.WriteLine("线程耗时:" + watch.ElapsedMilliseconds); Console.WriteLine("线程输出:" + result);
运行结果如下:
4.2 ManualResetEvent
和AutoResetEvent 相对的还有一个 ManualResetEvent 手动模式,他们的区别在于,在线程结束后ManualResetEvent 还是可以通行的,除非手动Reset关闭。下面看一个示例:
先定义一个手动通知的对象:
static EventWaitHandle mre = new ManualResetEvent(false);
创建线程:
System.Diagnostics.Stopwatch watch = System.Diagnostics.Stopwatch.StartNew(); Thread myThreadFirst = new Thread(() => { Thread.Sleep(1000); result = 100; mre.Set(); }) { Name = "线程一" }; Thread myThreadSecond = new Thread(() => { mre.WaitOne(); Console.WriteLine(Thread.CurrentThread.Name + "获取结果:" + result + "("+System.DateTime.Now.ToString()+")"); }) {}; myThreadFirst.Start(); myThreadSecond.Start(); mre.WaitOne(); Console.WriteLine("线程耗时:" + watch.ElapsedMilliseconds + "(" + System.DateTime.Now.ToString() + ")"); Console.WriteLine("线程输出:" + result + "(" + System.DateTime.Now.ToString() + ")");
运行结果如下:
4.3. Semaphore
Semaphore也是线程通知的一种,上面的通知模式,在线程开启的数量很多的情况下,使用Reset()关闭时,如果不使用Sleep休眠一下,很有可能导致某些线程没有恢复的情况下,某一线程提前关闭,对于这种很难预测的情况,.NET提供了更高级的通知方式Semaphore,可以保证在超多线程时不会出现上述问题。
先定义一个通知对象的静态字段:
复制代码 代码如下:
static Semaphore sem = new Semaphore(2, 2);
使用循环创建100个线程:
for (int i = 1; i <= 100; i++) { new Thread(() => { sem.WaitOne(); Thread.Sleep(30); Console.WriteLine(Thread.CurrentThread.Name+" "+DateTime.Now.ToString()); sem.Release(); }) {+i}.Start(); }
运行结果如下:
可以看到完整的输出我们所想要看到的结果。
5. 本节要点:
A.线程中静态字段的ThreadStatic特性,使用该字段在不同线程中拥有不同的值
B.线程同步的几种方式,线程锁和线程通知
C.线程通知的两种方式:AutoResetEvent /ManualResetEvent 和 Semaphore
到此为止.net面向对象之多线程(Multithreading)及多线程高级应用介绍到此为止。
您可能感兴趣的文章: