C#多线程学习之:Monitor类
?
關于對C#多線程類Monitor的理解
??
1、對線程的理解
圍繞著鎖周圍的線程可以分為以下三類:
l? 擁有鎖的線程:只有一個
l? 就緒隊列:只有就緒隊列里的線程才有機會在鎖被釋放時去獲取鎖。
l? 等待隊列:沒有資格去獲取鎖。
?
2、Monitor.Wait(obj)方法
當線程調用 Wait 時,它釋放對象的鎖并進入對象的等待隊列,對象的就緒隊列中的下一個線程(如果有)獲取鎖并擁有對對象的獨占使用。
Wait(obj)就是交出鎖的使用權,把自己移到等待隊列里,處于阻塞狀態,當再次獲得鎖時(得先收到脈沖信號移動到就緒隊列然后其他線程釋放鎖)返回true并且線程繼續執行,否則不返回一直阻塞。
?
3、Monitor.Pulse方法
通知(也就是發出脈沖信號)等待隊列中的線程鎖定對象的狀態即將發生更改。接收到脈沖后,等待線程就被移動到就緒隊列中。在鎖定對象被解鎖后,就緒隊列中的下一個線程(不一定是接收到脈沖的線程)將獲得該鎖。pulse()并不會使當前線程釋放鎖。
?
4、獲取鎖的過程
當一個線程嘗試著lock一個同步對象的時候,該線程就在就緒隊列中排隊。一旦沒人擁有該同步對象,就緒隊列中的線程就可以占有該同步對象。這也是我們平時最經常用的lock方法。
為了其他的同步目的,占有同步對象的線程也可以暫時放棄同步對象,并把自己流放到等待隊列中去。這就是Monitor.Wait。由于該線程放棄了同步對象,其他在就緒隊列的排隊者就可以進而擁有同步對象。
比起就緒隊列來說,在等待隊列中排隊的線程更像是二等公民:他們不能自動得到同步對象,甚至不能自動移動到就緒隊列。而Monitor.Pulse的作用就是開一次門,使得一個正在等待隊列中的線程移動到就緒隊列;相應的Monitor.PulseAll則打開門放所有等待隊列中的線程到就緒隊列。
?
5、Monitor.Wait(obj,timeOut)
阻塞自己后把自己調到等待線程,直到再次獲得鎖才返回繼續執行。
關于該方法的一些理解分析:
l? 第二個參數 tiemout表示線程釋放鎖進入等待隊列后到進入就緒隊列之前等待的一個限定時間(單位是毫秒)。
l? 如果在限定時間內再次獲得鎖(包括收到脈沖信號然后移到就緒隊列并且其他線程釋放鎖)就返回true然后繼續運行;
l? 如果在限定時間內沒有收到脈沖信號,超時后,就被移到就緒隊列,直到獲得鎖才返回,返回false;
l? 如果在限定時間內收到脈沖信號,移動到就緒隊列,直到獲得鎖才返回,返回true;
l? 該方法只會在再次獲得鎖時才會返回,否則一直阻塞(一開始是在等待隊列,最終會被移動到就緒隊列);
l? 建議:pulse后直接wait,中間別放其他代碼。因為Monitor.Wait(obj,timeOut) 方法返回false還是true取決于在限定時間內是否收到脈沖信號從而移到就緒隊列;
?
關于lock、線程池和定時器的簡單介紹
l? Lock是一個語法糖,效果相當于Monitor的TryEnter和Exit方法
l? Lock鎖定的對象建議是類的一個static對象,詳情見 http://www.cnblogs.com/xd125/archive/2007/12/12/992406.html
l? 線程池 http://www.cnblogs.com/huangxincheng/archive/2012/03/18/2405039.html
?
DispatcherTimer類的使用
DispatcherTimer類位于System.Windows.Threading命名空間下,類似于winform的Timer類。
{ DispatcherTimer timer = new DispatcherTimer(); timer.Interval = TimeSpan.FromSeconds(1); timer.Tick += new EventHandler(timer_Tick); } void timer_Tick(object sender, EventArgs e) { tb.Text = DateTime.Now.ToLongTimeString(); } 上面的代碼演示了一個簡單的時鐘程序,每隔一秒中更新一次時間
l??
?
?????????????
轉載于:https://www.cnblogs.com/zouzf/p/3305643.html
總結
以上是生活随笔為你收集整理的C#多线程学习之:Monitor类的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 机器学习算法及应用领域相关的中国大牛
- 下一篇: C#通过接口与线程通信(捕获线程状态)介