c# monitor鎖


 
         

   當多個線程在並發的時候,難免會碰到相互沖突的事情,比如最經典的ATM機的問題,並發不可怕,可怕的是我們沒有能力控制。

線程以我的理解可以分為三種

① 鎖。

② 互斥。

③ 信號。

  好,這一篇主要整理“鎖”,C#提供了2種手工控制的鎖

一:  Monitor類

     這個算是實現鎖機制的純正類,在鎖定的臨界區中只允許讓一個線程訪問,其他線程排隊等待。主要整理為2組方法。

 

1:Monitor.Enter和Monitor.Exit

         微軟很照護我們,給了我們語法糖Lock,對的,語言糖確實減少了我們不必要的勞動並且讓代碼更可觀,但是如果我們要精細的

     控制,則必須使用原生類,這里要注意一個問題就是“鎖住什么”的問題,一般情況下我們鎖住的都是靜態對象,我們知道靜態對象

     屬於類級別,當有很多線程共同訪問的時候,那個靜態對象對多個線程來說是一個,不像實例字段會被認為是多個。

 

 

2:Monitor.Wait和Monitor.Pulse

 首先這兩個方法是成對出現,通常使用在Enter,Exit之間。

 Wait: 暫時的釋放資源鎖,然后該線程進入”等待隊列“中,那么自然別的線程就能獲取到資源鎖。

 Pulse:  喚醒“等待隊列”中的線程,那么當時被Wait的線程就重新獲取到了鎖。






using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; namespace ConsoleApplication3 { class Program { static void Main(string[] args) { for (int i = 0; i < 100; i++) { Thread t = new Thread(run); t.Start(); } Console.ReadKey(); } static object obj = new object(); static int count = 0; static void run() { Thread.Sleep(10); Monitor.Enter(obj); Console.WriteLine(++count); Monitor.Exit(obj); } } }

  

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;

namespace Test
{
    public class Program
    {
        public static void Main(string[] args)
        {
            LockObj obj = new LockObj();

            //注意,這里使用的是同一個資源對象obj
            Jack jack = new Jack(obj);
            John john = new John(obj);

            Thread t1 = new Thread(new ThreadStart(jack.Run));
            Thread t2 = new Thread(new ThreadStart(john.Run));

            t1.Start();
            t1.Name = "Jack";

            t2.Start();
            t2.Name = "John";

            Console.ReadLine();
        }
    }

    //鎖定對象
    public class LockObj { }

    public class Jack
    {
        private LockObj obj;

        public Jack(LockObj obj)
        {
            this.obj = obj;
        }

        public void Run()
        {
            Monitor.Enter(this.obj);

            Console.WriteLine("{0}:今天我值班嗎?看下", Thread.CurrentThread.Name);

            Console.WriteLine("{0}:原來是jon值班呀,那我走呀", Thread.CurrentThread.Name);

            //暫時的釋放鎖資源
            Monitor.Wait(this.obj);

            Console.WriteLine("{0}:那行吧", Thread.CurrentThread.Name);

            //喚醒等待隊列中的線程
            Monitor.Pulse(this.obj);

            Console.WriteLine("{0}:呵呵", Thread.CurrentThread.Name);

            Monitor.Exit(this.obj);
        }
    }

    public class John
    {
        private LockObj obj;

        public John(LockObj obj)
        {
            this.obj = obj;
        }

        public void Run()
        {
            Monitor.Enter(this.obj);

            Console.WriteLine("{0}:哥們,今天我有點事情,你幫我下唄",
                               Thread.CurrentThread.Name);

            //喚醒等待隊列中的線程
            Monitor.Pulse(this.obj);

            Console.WriteLine("{0}:謝謝兄弟了", Thread.CurrentThread.Name);

            //暫時的釋放鎖資源
            Monitor.Wait(this.obj);

            Console.WriteLine("{0}:哈哈", Thread.CurrentThread.Name);

            Monitor.Exit(this.obj);
        }
    }
}

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM