我讀這篇文章https://www.codeproject.com/Articles/28785/Thread-synchronization-Wait-and-Pulse-demystified#_articleTop當ThreadB Monitor.Pulse(_locker)哪個線程會首先得到_locker?
有一個報價:
推薦模式
這些隊列會導致意外的行爲。發生脈衝時,等待隊列的頭部被釋放並被添加到就緒隊列中。但是,如果就緒隊列中有其他線程,則它們將在釋放線程之前獲取鎖。這是一個問題,因爲獲取鎖的線程可能會改變脈衝線程所依賴的狀態。
的解決方案是使用lock語句內while條件:
readonly object key = new object(); bool block = true; // thread A lock (key) { while (block) Monitor.Wait(key); block = true; } // thread B lock (key) { block = false; Monitor.Pulse(key); }
作者說ThreadC將得到_locker第一,但在我的演示中,我跑三個線程我發現這是不真正。 ThreadC最後得到_locker。
這裏是我的代碼:
class Program
{
private static readonly object _locker = new object();
public static void ThreadA()
{
new Thread(() =>
{
lock (_locker)
{
Console.WriteLine("Thread A acquire lock then wait threadId {0}", Thread.CurrentThread.ManagedThreadId);
Monitor.Wait(_locker);
Thread.Sleep(1000);
Console.WriteLine("Thread A Continue .. threadId {0}", Thread.CurrentThread.ManagedThreadId);
}
}).Start();
}
public static void ThreadB()
{
new Thread(() =>
{
lock (_locker)
{
Console.WriteLine("Thread B acquire lock...then pulse threadId {0}",Thread.CurrentThread.ManagedThreadId);
Monitor.Pulse(_locker);
Thread.Sleep(1000);
Console.WriteLine("Thread B sleep...then realse the locker threadId {0}", Thread.CurrentThread.ManagedThreadId);
}
}).Start();
}
public static void ThreadC()
{
new Thread(ThreadA).Start();
}
static void Main(string[] args)
{
ThreadA();
Thread.Sleep(10); // ensure threadA get _locker firstly
ThreadB();
ThreadC();
}
}
顯示測試程序的輸出。 –