中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

C# Monitor類的使用

發布時間:2020-07-30 18:43:19 來源:網絡 閱讀:2086 作者:13713878410 欄目:編程語言

C#中, 通過System.Threading.Monitor類可以實現多線程中對某些代碼塊的同步訪問,以確保數據的安全性。


object obj=new object();

Monitor在鎖對象obj上會維持兩個線程隊列R和W以及一個引用T :

(1) T是對當前獲得了obj鎖的線程的引用(設此線程為CurrThread); 

(2) R為就緒隊列, 其上的線程已經準備好獲取obj鎖。當obj鎖被CurrThread釋放后(CurrThread可通過Monitor.Exit(obj)或 Monitor.Wait(obj)來釋放其所獲的obj鎖)這些線程就會去競爭obj鎖,獲得obj鎖的線程將被T引用; 線程調用Monitor.Enter(obj)或Monitor.TryEnter(obj)將會使該線程直接進入R隊列。

(3) W為等待隊列,其上的線程是因為調用了Monitor.Wait(obj)而進入W隊列的;W上的線程不會被OS直接調度執行,也就是說它們沒有準備好獲取obj鎖,就是說在等待隊列上的線程不能去獲得obj鎖當前獲得obj鎖的線程CurrThread調用Monitor.Pulse(obj)或Monitor.PulseAll(obj)后會使W隊列中的第一個等待線程或所有等待線程被移至R隊列,這時被移至R隊列的這些線程就有機會被OS直接調度執行,也就是有可以去競爭obj鎖。


Monitor類中的重要方法:

方法名稱
描述
void Enter(object obj)Acquires an exclusive lock on the specified object.
void Enter(object obj, ref bool lockTaken)Acquires an exclusive lock on the specified object, and atomically sets a value that indicates whether the lock was taken.
void Exit(object obj)Releases an exclusive lock on the specified object.
void Pulse(object obj)Notifies a thread in the waiting queue of a change in the locked object's state.
void PulseAll(object obj)Notifies all waiting threads of a change in the object's state.
bool TryEnter(object obj)Attempts to acquire an exclusive lock on the specified object.
bool TryEnter(object obj, int millisecondsTimeout)Attempts, for the specified number of milliseconds, to acquire an exclusive  lock on the specified object.
bool Wait(object obj)Releases the lock on an object and blocks the current thread until it reacquires
the lock. If the specified time-out interval elapses, the thread enters the ready queue.

例子1:

private object lockObj = new object();
        private void Execute()
        {
            Monitor.Enter(lockObj);
            for (int i = 0; i < 5;i++ )
            {
                Console.WriteLine("Thread Name:" + Thread.CurrentThread.Name + ", Count:" + i);
                Thread.Sleep(new Random().Next(5000));
            }
            Monitor.Exit(lockObj);
        }
        public void Test()
        {
            Thread thread1 = new Thread(new ThreadStart(Execute));
            thread1.Name = "Thread1";
            thread1.Start();
            Thread thread2 = new Thread(new ThreadStart(Execute));
            thread2.Name = "Thread2";
            thread2.Start();
            
            thread1.Join();
            thread2.Join();
        }


輸出結果:

Thread Name:Thread1, Count:0
Thread Name:Thread1, Count:1
Thread Name:Thread1, Count:2
Thread Name:Thread1, Count:3
Thread Name:Thread1, Count:4
Thread Name:Thread2, Count:0
Thread Name:Thread2, Count:1
Thread Name:Thread2, Count:2
Thread Name:Thread2, Count:3
Thread Name:Thread2, Count:4


例子2:

         private void Execute1()
        {
            if (Monitor.TryEnter(lockObj,1000))
            {
                for (int i = 0; i < 5; i++)
                {
                    Console.WriteLine("Thread Name:" + Thread.CurrentThread.Name + ", Count:" + i);
                    Thread.Sleep(new Random().Next(5000));
                }
                Monitor.Exit(lockObj);
            }
        }
        public void Test1()
        {
            Thread thread1 = new Thread(new ThreadStart(Execute1));
            thread1.Name = "Thread1";
            thread1.Start();
            Thread thread2 = new Thread(new ThreadStart(Execute1));
            thread2.Name = "Thread2";
            thread2.Start();
           
            thread1.Join();
            thread2.Join();
        }


輸出結果:

Thread Name:Thread1, Count:0
Thread Name:Thread1, Count:1
Thread Name:Thread1, Count:2
Thread Name:Thread1, Count:3
Thread Name:Thread1, Count:4

因為Thread2嘗試獲取鎖失敗,所以沒有執行鎖內部的代碼塊。


例子3:

        private Queue queue = new Queue();
        public void SendThread()
        {
            int counter = 0;
            lock (queue)
            {
                while (counter < 5)
                {
                    //Wait, if the queue is busy.
                    Monitor.Wait(queue);
                    //Push one element.
                    queue.Enqueue(counter);
                    //Release the waiting thread.
                    Monitor.Pulse(queue);
                    counter++;
                }
            }
        }
        public void ConsumeThread()
        {
            lock (queue)
            {
                //Release the waiting thread.
                Monitor.Pulse(queue);
                //Wait in the loop, while the queue is busy.
                //Exit on the time-out when the first thread stops.
                while (Monitor.Wait(queue, 1000))
                {
                    //Pop the first element.
                    int counter = (int)queue.Dequeue();
                    //Print the first element.
                    Console.WriteLine("Queue Value:" + counter.ToString());
                    //Release the waiting thread.
                    Monitor.Pulse(queue);
                }
            }
        }
        public void Test2()
        {
            Thread thread1 = new Thread(new ThreadStart(SendThread));
            thread1.Name = "Thread1";
            thread1.Start();
            Thread thread2 = new Thread(new ThreadStart(ConsumeThread));
            thread2.Name = "Thread2";
            thread2.Start();
            thread1.Join();
            thread2.Join();
            Console.WriteLine("Queue Size:" + queue.Count);
        }

輸出結果:

Queue Value:0
Queue Value:1
Queue Value:2
Queue Value:3
Queue Value:4
Queue Size:0

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

山丹县| 通州市| 庄浪县| 井陉县| 中西区| 镇江市| 涿鹿县| 德庆县| 连云港市| 竹山县| 景东| 嘉祥县| 南溪县| 房产| 夏津县| 渝北区| 中超| 长岭县| 定西市| 麦盖提县| 阿克苏市| 四会市| 北安市| 岚皋县| 定边县| 博罗县| 克山县| 晋中市| 特克斯县| 二连浩特市| 阳山县| 南宁市| 平湖市| 育儿| 得荣县| 阜新市| 乡城县| 泰州市| 永平县| 颍上县| 荔浦县|