1. 程式人生 > >ManualResetEvent和AutoResetEvent——多執行緒

ManualResetEvent和AutoResetEvent——多執行緒

初次體驗

ManualResetEvent和AutoResetEvent主要負責多執行緒程式設計中的執行緒同步;以下一段是引述網上和MSDN的解析:

在.Net多執行緒程式設計中,AutoResetEvent和ManualResetEvent這兩個類經常用到, 他們的用法很類似,但也有區別。Set方法將訊號置為傳送狀態,Reset方法將訊號置為不傳送狀態,WaitOne等待訊號的傳送。可以通過建構函式的引數值來決定其初始狀態,若為true則非阻塞狀態,為false為阻塞狀態。如果某個執行緒呼叫WaitOne方法,則當訊號處於傳送狀態時,該執行緒會得到訊號, 繼續向下執行。其區別就在呼叫後,AutoResetEvent.WaitOne()每次只允許一個執行緒進入,當某個執行緒得到訊號後,AutoResetEvent會自動又將訊號置為不傳送狀態,則其他呼叫WaitOne的執行緒只有繼續等待.也就是說,AutoResetEvent一次只喚醒一個執行緒;而ManualResetEvent則可以喚醒多個執行緒,因為當某個執行緒呼叫了ManualResetEvent.Set()方法後,其他呼叫WaitOne的執行緒獲得訊號得以繼續執行,而ManualResetEvent不會自動將訊號置為不傳送。也就是說,除非手工呼叫了ManualResetEvent.Reset()方法,則ManualResetEvent將一直保持有訊號狀態,ManualResetEvent也就可以同時喚醒多個執行緒繼續執行。

本質上AutoResetEvent.Set()方法相當於ManualResetEvent.Set()+ManualResetEvent.Reset();

因此AutoResetEvent一次只能喚醒一個執行緒,其他執行緒還是堵塞

生動示例

用一個三國演義的典故來寫段示例程式碼:

話說曹操率領80W大軍準備圍剿劉備和孫權,面對敵眾我寡的情況,諸葛亮與周瑜想到了一個妙計,用裝滿火藥桶的大船去衝擊曹操連在一起的戰船,計劃都安排好了,可謂“萬事俱備 只欠東風”。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; namespace Test { class Program { //預設訊號為不傳送狀態 private static ManualResetEvent mre = new ManualResetEvent(false); static