描述C#多線程中 lock關鍵字

來源:互聯網
上載者:User

述C#多線程中 lock關鍵字

  本文介紹C# lock關鍵字,C#提供了一個關鍵字lock,它可以把一段代碼定義為互斥段(critical section),互斥段在一個時刻內只允許一個線程進入執行,而其他線程必須等待。

  每個線程都有自己的資源,但是代碼區是共用的,即每個線程都可以執行相同的函數。這可能帶來的問題就是幾個線程同時執行一個函數,導致資料的混亂,產生不可預料的結果,因此我們必須避免這種情況的發生。

C#提供了一個關鍵字lock,它可以把一段代碼定義為互斥段(critical section),互斥段在一個時刻內只允許一個線程進入執行,而其他線程必須等待。在C# lock關鍵字定義如下:

lock(expression) statement_block

expression代表你希望跟蹤的對象,通常是對象引用。

如果你想保護一個類的執行個體,一般地,你可以使用this;如果你想保護一個靜態變數(如互斥程式碼片段在一個靜態方法內部),一般使用類名就可以了。

而statement_block就是互斥段的代碼,這段代碼在一個時刻內只可能被一個線程執行。

下面是一個使用C# lock關鍵字的典型例子,在注釋裡說明了C# lock關鍵字的用法和用途。

樣本如下:

代碼 Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->using System; using System.Threading; namespace ThreadSimple{     internal class Account    {         int balance; //餘額        Random r=new Random();         internal Account(int initial)          {              balance=initial;         }        internal int Withdraw(int amount) //取回、取款        {             if(balance<0)             {                  //如果balance小於0則拋出異常                  throw new Exception("NegativeBalance");//負的 餘額             }             //下面的代碼保證在當前線程修改balance的值完成之前             //不會有其他線程也執行這段代碼來修改balance的值              //因此,balance的值是不可能小於0的              lock(this)              {                 Console.WriteLine("CurrentThread:"+Thread.CurrentThread.Name);                 //如果沒有lock關鍵字的保護,那麼可能在執行完if的條件判斷(成立)之後                  //另外一個線程卻執行了balance=balance-amount修改了balance的值                 //而這個修改對這個線程是不可見的,所以可能導致這時if的條件已經不成立了                 //但是,這個線程卻繼續執行 balance=balance-amount,所以導致balance可能小於0                 if(balance>=amount)                 {                     Thread.Sleep(5);                    balance=balance-amount;                     return  amount;                 }  else                 {                     return 0;                    //transactionrejected                 }             }          }        internal void DoTransactions()//取款事務        {            for (int i = 0; i < 100; i++)            {                Withdraw(r.Next(-50, 100));            }        }    }       internal class Test      {          static internal Thread[] threads=new Thread[10];         public static void Main()          {              Account acc=new Account(0);             for(int i=0;i<10;i++)             {                  Thread t=new Thread(new ThreadStart(acc.DoTransactions));                threads[i]=t;             }            for (int i = 0; i < 10; i++)            {                threads[i].Name = i.ToString();            }            for (int i = 0; i < 10; i++)            {                threads[i].Start();                Console.ReadLine();            }        }    } }

 

  本文介紹C# lock關鍵字,C#提供了一個關鍵字lock,它可以把一段代碼定義為互斥段(critical section),互斥段在一個時刻內只允許一個線程進入執行,而其他線程必須等待。

  每個線程都有自己的資源,但是代碼區是共用的,即每個線程都可以執行相同的函數。這可能帶來的問題就是幾個線程同時執行一個函數,導致資料的混亂,產生不可預料的結果,因此我們必須避免這種情況的發生。

C#提供了一個關鍵字lock,它可以把一段代碼定義為互斥段(critical section),互斥段在一個時刻內只允許一個線程進入執行,而其他線程必須等待。在C# lock關鍵字定義如下:

lock(expression) statement_block

expression代表你希望跟蹤的對象,通常是對象引用。

如果你想保護一個類的執行個體,一般地,你可以使用this;如果你想保護一個靜態變數(如互斥程式碼片段在一個靜態方法內部),一般使用類名就可以了。

而statement_block就是互斥段的代碼,這段代碼在一個時刻內只可能被一個線程執行。

下面是一個使用C# lock關鍵字的典型例子,在注釋裡說明了C# lock關鍵字的用法和用途。

樣本如下:

代碼 Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->using System; using System.Threading; namespace ThreadSimple{     internal class Account    {         int balance; //餘額        Random r=new Random();         internal Account(int initial)          {              balance=initial;         }        internal int Withdraw(int amount) //取回、取款        {             if(balance<0)             {                  //如果balance小於0則拋出異常                  throw new Exception("NegativeBalance");//負的 餘額             }             //下面的代碼保證在當前線程修改balance的值完成之前             //不會有其他線程也執行這段代碼來修改balance的值              //因此,balance的值是不可能小於0的              lock(this)              {                 Console.WriteLine("CurrentThread:"+Thread.CurrentThread.Name);                 //如果沒有lock關鍵字的保護,那麼可能在執行完if的條件判斷(成立)之後                  //另外一個線程卻執行了balance=balance-amount修改了balance的值                 //而這個修改對這個線程是不可見的,所以可能導致這時if的條件已經不成立了                 //但是,這個線程卻繼續執行 balance=balance-amount,所以導致balance可能小於0                 if(balance>=amount)                 {                     Thread.Sleep(5);                    balance=balance-amount;                     return  amount;                 }  else                 {                     return 0;                    //transactionrejected                 }             }          }        internal void DoTransactions()//取款事務        {            for (int i = 0; i < 100; i++)            {                Withdraw(r.Next(-50, 100));            }        }    }       internal class Test      {          static internal Thread[] threads=new Thread[10];         public static void Main()          {              Account acc=new Account(0);             for(int i=0;i<10;i++)             {                  Thread t=new Thread(new ThreadStart(acc.DoTransactions));                threads[i]=t;             }            for (int i = 0; i < 10; i++)            {                threads[i].Name = i.ToString();            }            for (int i = 0; i < 10; i++)            {                threads[i].Start();                Console.ReadLine();            }        }    } }

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.