http://www.codeproject.com/Articles/28785/Thread-synchronization-Wait-and-Pulse-demystifiedMonitor.Pulse與等待 - 意外的行爲
隊列:
就緒隊列是線程正在等待一個 特定的鎖集合。 Monitor.Wait方法引入了另一個隊列: 等待隊列。這是必需的,因爲等待脈衝不同於等待獲取鎖定 。像就緒隊列一樣,等待的隊列是 。
推薦模式:
這些隊列可能會導致意外的行爲。當發生脈衝時,等待隊列的頭部被釋放,並被添加到準備好的 隊列中。但是,如果就緒隊列中有其他線程,它們將在發佈的線程之前獲取該鎖。這是一個 問題,因爲獲取該鎖的線程可能會改變脈衝線程所依賴的狀態 。解決辦法是在鎖定語句內使用 條件
* Q =隊列。
由此我明白,當我打電話給Pulse
時,它會在結束之前做兩件事情。首先,它將一個線程從等待中的Q中移除到準備好的Q上。其次,它讓Ready Q中的一個線程(不知道該線程是誰)獲取鎖定;它並不關心誰獲取鎖(來自等待Q的線程或由於某種原因處於準備好Q的線程)。
如果我是正確的關於然後爲什麼是把一個while
前Monitor.Wait
幫助解決這個問題(問題 - 脈衝結束即使從等待Q來到線程沒有獲取鎖)?
A。 告訴我,如果我對Monitor.Pulse
的目的是正確的。
B。 爲什麼我需要把下面的答案的while
前Monitor.Wait
的完整代碼:
class Program
{
static Queue<int> queue = new Queue<int>();
static object someMonitor = new object();
static void Main(string[] args)
{
Thread Thread1 = new Thread(WorkAlltheTime);
Thread1.Name = "Thread1";
Thread Thread2 = new Thread(WorkAlltheTime);
Thread2.Name = "Thread2";
Thread Thread3 = new Thread(WorkOnce);
Thread3.Name = "Thread3";
Thread1.Start();
Thread2.Start();
Thread.Sleep(1000);
Thread3.Start();
Console.ReadLine();
}
static void WorkAlltheTime()
{
Console.WriteLine("Came in to Ready Q: " + Thread.CurrentThread.Name);
lock (someMonitor)
{
Console.WriteLine("Came out from Ready Q: " + Thread.CurrentThread.Name);
// Broken!
while (queue.Count == 0)
{
Console.WriteLine("Came in to Waiting Q: " + Thread.CurrentThread.Name);
Monitor.Wait(someMonitor);
Console.WriteLine("Came out from Waiting Q: " + Thread.CurrentThread.Name);
}
queue.Dequeue();
Console.WriteLine("Thread: "+Thread.CurrentThread.Name+" Pulled Out");
}
}
static void WorkOnce()
{
lock (someMonitor)
{
queue.Enqueue(1);
Monitor.Pulse(someMonitor);
}
}
}
謝謝你,我寫了你的例子的完整代碼,並用你的解釋我測試了90次,現在我完全理解了。謝謝Agian! –