using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;ide
namespace 線程同步問題
{
class Program
{
/// <summary>
/// 首先聲明一個事件類,其實是這樣的用這個類的實例對象去控制兩個線程之間的同步。原理是這樣的這個對象有兩種狀態,若是這個對象是終止狀態和非終止狀態。若是這個對象是終止狀態,
/// 那這個對象調用其等待狀態時候,調用waitone時阻塞被當即釋放,也就是沒有起到阻塞的做用;而後由於這個對象模式是autoReset;因此這個對象會被置爲非終止狀態。
/// 因此此次再調用阻塞方法,那就會阻塞這個線程。
/// 疑問:
/// autoReset是說被釋放一次後會根據模式決定是不是在非終止狀態。其實是對釋放後狀態的判斷。
/// waitone:若是是被置爲終止狀態,線程被永遠執行,執行開始後被置爲非終止狀態。等待下一次被阻塞。
/// 疑問:什麼狀況下會阻塞線程。什麼狀況下會釋放線程。
/// 阻塞線程,非終止狀態下,調用waitone等一下的方法,這個是在同一個線程內的。線程終止
/// 終止狀態下,調用waitone等一下的方法,線程不終止繼續執行。
/// 三個方法:waitone(),set(),reset()
/// waitone()是阻塞這個線程
/// set()是釋放被阻塞的線程
/// reset()是設置這個類是非終止狀態。
/// 終止狀態:應該叫可否使用狀態;若是是true就是不能使用;就是終止狀態;若是是false就是能使用,非終止狀態。
/// 只有在非終止狀態下,才能使用這個waitone纔有做用。set纔有做用。waitone(),set()是使其設置成終止狀態,就是不阻塞狀態,只有reset()才能起做用。
/// 並且在阻塞被釋放時,觸發是否把狀態設置回非終止狀態的動做。
/// 實質:這個實質應該是一個待條件的循環。若是是終止狀態,調用waitone()線程不阻塞,若是是非終止狀態,調用waitone()是阻塞,
///
///
///
/// 具體使用流程:
/// 調用waitone()阻塞:看是否能阻塞,能就阻塞,不能就不阻塞。再根據是否自動恢復爲可以使用決定事件狀態。
/// 能阻塞,調用set中止阻塞線程,並設置阻塞不可以使用。再根據是否自動恢復爲可以使用決定事件狀態。
/// 不能阻塞,要手動設置爲非終止狀態,方法是:reset().
///
///
/// 另外一線程決定此線程是否阻塞。set()是另外一線程處理的
///
///
/// 固然也能夠在本線程內處理。
///
///
/// </summary>
static EventWaitHandle eHandle;測試
static void UnblockDemo()
{
Console.WriteLine("測試EventWaitHandle的初始終止狀態");
eHandle = new EventWaitHandle(true, EventResetMode.AutoReset);//eHandle初始爲終止狀態,模式爲AutoReset
eHandle.WaitOne();//因爲EventWaitHandle對象eHandle初始狀態爲終止狀態,因此這裏第一次調用WaitOne時阻塞被當即釋放,又因爲eHandle爲AutoReset模式,因此以後eHandle會被置爲非終止狀態
Console.WriteLine("線程未被阻塞");
eHandle.WaitOne();//因爲此時eHandle已經爲非終止狀態,因此此時調用WaitOne線程會被阻塞
Console.WriteLine("線程被阻塞");
}spa
static void BlockDemo()
{
Console.WriteLine("測試EventWaitHandle的初始非終止狀態");
eHandle = new EventWaitHandle(false, EventResetMode.AutoReset);//eHandle初始爲非終止狀態,模式爲AutoReset
eHandle.WaitOne();//因爲EventWaitHandle對象eHandle初始狀態爲非終止狀態,因此這裏第一次調用WaitOne時,線程就被組塞了;autoReset指是否被回覆爲非終止狀態。
Console.WriteLine("線程被阻塞");
}線程
static void AutoResetDemo()
{
Console.WriteLine("測試EventWaitHandle的AutoReset模式");
eHandle = new EventWaitHandle(false, EventResetMode.AutoReset);//eHandle初始爲非終止狀態,模式爲AutoReset
///啓動另外一個線程
//ThreadPool.QueueUserWorkItem(new WaitCallback((object o) =>
//{
// //啓動另外一個線程,每隔3秒鐘調用一次eHandle.Set方法,爲主線程釋放一次阻塞,一共釋放3次
// for (int i = 0; i < 3; i++)
// {
// Thread.Sleep(3000);
// eHandle.Set();//因爲eHandle處於AutoReset模式,因此每次使用Set將eHandle置爲終止狀態後,待被WaitOne阻塞的線程被釋放後,eHandle又會被自動置回非終止狀態
// }
//}), null);
ThreadPool.QueueUserWorkItem(new WaitCallback(
(object o) =>
{對象
//啓動另外一個線程,每隔3秒鐘調用一次eHandle.Set方法,爲主線程釋放一次阻塞,一共釋放3次
for (int i = 0; i < 3; i++)
{
Thread.Sleep(3000);
eHandle.Set();//因爲eHandle處於AutoReset模式,因此每次使用Set將eHandle置爲終止狀態後,待被WaitOne阻塞的線程被釋放後,eHandle又會被自動置回非終止狀態
}事件
}同步
),null);
eHandle.WaitOne();//線程第一次被WaitOne阻塞
Console.WriteLine("第一次WaitOne調用阻塞已被釋放,3秒後第二次WaitOne調用的阻塞會被釋放");
eHandle.WaitOne();//線程第二次被WaitOne阻塞
Console.WriteLine("第二次WaitOne調用阻塞已被釋放,3秒後第三次WaitOne調用的阻塞會被釋放");
eHandle.WaitOne();//線程第三次被WaitOne阻塞
Console.WriteLine("第三次WaitOne調用阻塞已被釋放,全部WaitOne調用的阻塞都已被釋放");
}string
static void ManualResetDemo()
{
Console.WriteLine("測試EventWaitHandle的ManualReset模式");
eHandle = new EventWaitHandle(false, EventResetMode.ManualReset);//eHandle初始爲非終止狀態,模式爲ManualReset
ThreadPool.QueueUserWorkItem(new WaitCallback((object o) =>
{
//啓動另外一線程,3秒後調用一次eHandle.Set方法,爲主線程釋放WaitOne阻塞
Thread.Sleep(3000);
eHandle.Set();//因爲eHandle處於ManualReset模式,因此一旦使用Set將eHandle置爲終止狀態後,在eHandle的Reset被調用前eHandle會一直處於終止狀態,在eHandle調用Reset前,全部被WaitOne阻塞的線程會當即獲得釋放
}), null);it
eHandle.WaitOne();//線程第一次被WaitOne阻塞
Console.WriteLine("第一次WaitOne調用阻塞已被釋放,第二次WaitOne調用的阻塞會被當即釋放");
eHandle.WaitOne();//線程第二次被WaitOne阻塞
Console.WriteLine("第二次WaitOne調用阻塞已被釋放,第三次WaitOne調用的阻塞會被當即釋放");
eHandle.WaitOne();//線程第三次被WaitOne阻塞
Console.WriteLine("第三次WaitOne調用阻塞已被釋放,全部WaitOne調用的阻塞都已被釋放");io
eHandle.Reset();//調用eHandle的Reset方法,將eHandle手動置回非終止狀態,以後再調用WaitOne方法就會被阻塞了
eHandle.WaitOne();//線程第四次被WaitOne阻塞
Console.WriteLine("第四次WaitOne調用阻塞已被釋放");
}
static void Main(string[] args) { Console.Write("你想測試哪個方法1=UnblockDemo,2=BlockDemo,3=AutoResetDemo,4=ManualResetDemo:"); switch (Console.ReadLine()) { case "1": UnblockDemo(); break; case "2": BlockDemo(); break; case "3": AutoResetDemo(); break; case "4": ManualResetDemo(); break; default: break; } } } }