zoukankan      html  css  js  c++  java
  • C# 多线程互斥锁

    lock    關鍵字可將陳述式區塊標記為關鍵區段 (Critical Section),其做法是為指定的物件取得互斥鎖定、執行陳述式,接著釋出該鎖定。             下列範例包含一個 lock 陳述式。

     1     class Account
     2     {
     3         decimal balance;
     4         private Object thisLock = new Object();
     5 
     6         public void Withdraw(decimal amount)
     7         {
     8             lock (thisLock)
     9             {
    10                 if (amount > balance)
    11                 {
    12                     throw new Exception("Insufficient funds");
    13                 }
    14                 balance -= amount;
    15             }
    16         }
    17     }

     

    備註            

                
              

    lock   關鍵字可保證有執行緒在關鍵區段時,絕對不會有任何其他執行緒同時也進入這個關鍵區段執行。               如果其他執行緒嘗試進入已鎖定的程式碼,它將會等候、封鎖,直到該物件被釋出。 

    執行緒 (C# 和 Visual Basic)   這一章節會討論執行緒的處理。                       

    lock   關鍵字會在區塊開始執行時呼叫 Enter,並在區塊結束時呼叫 Exit。               ThreadInterruptedException   擲回,如果 Interrupt 中斷等待進入 lock 陳述式的執行緒。 

    一般而言,請避免鎖定 public 型別或程式碼無法控制的執行個體。               有三種常見的建構,分別為 lock (this)lock (typeof (MyType))lock ("myLock"),違反這項方針: 

    • lock (this) 在可公開存取執行個體的情況下,會是問題所在。                               

    • lock (typeof (MyType)) 在可公開存取 MyType 的情況下,會是問題所在。                               

    • lock("myLock") 會是問題所在,因為使用相同字串的處理序中若有任何其他程式碼,將會共用相同的鎖定。                               

    最佳作法是定義要鎖定的 private 物件,或者定義 private static 物件變數保護所有執行個體通用的資料。                       

    您在 lock 陳述式的主體中不能使用 等候 關鍵字。                        

    範例            

    以下的範例顯示在 C# 中執行緒 (但不用鎖定) 的簡易用法。    
        //using System.Threading;
    
        class ThreadTest
        {
            public void RunMe()
            {
                Console.WriteLine("RunMe called");
            }
    
            static void Main()
            {
                ThreadTest b = new ThreadTest();
                Thread t = new Thread(b.RunMe);
                t.Start();
            }
        }
        // Output: RunMe called

    下列範例使用到執行緒與 lock。               只要 lock 陳述式存在,此陳述式區塊就是關鍵區段,而且 balance 永遠不會成為負數。

     1     // using System.Threading;
     2 
     3     class Account
     4     {
     5         private Object thisLock = new Object();
     6         int balance;
     7 
     8         Random r = new Random();
     9 
    10         public Account(int initial)
    11         {
    12             balance = initial;
    13         }
    14 
    15         int Withdraw(int amount)
    16         {
    17 
    18             // This condition never is true unless the lock statement
    19             // is commented out.
    20             if (balance < 0)
    21             {
    22                 throw new Exception("Negative Balance");
    23             }
    24 
    25             // Comment out the next line to see the effect of leaving out 
    26             // the lock keyword.
    27             lock (thisLock)
    28             {
    29                 if (balance >= amount)
    30                 {
    31                     Console.WriteLine("Balance before Withdrawal :  " + balance);
    32                     Console.WriteLine("Amount to Withdraw        : -" + amount);
    33                     balance = balance - amount;
    34                     Console.WriteLine("Balance after Withdrawal  :  " + balance);
    35                     return amount;
    36                 }
    37                 else
    38                 {
    39                     return 0; // transaction rejected
    40                 }
    41             }
    42         }
    43 
    44         public void DoTransactions()
    45         {
    46             for (int i = 0; i < 100; i++)
    47             {
    48                 Withdraw(r.Next(1, 100));
    49             }
    50         }
    51     }
    52 
    53     class Test
    54     {
    55         static void Main()
    56         {
    57             Thread[] threads = new Thread[10];
    58             Account acc = new Account(1000);
    59             for (int i = 0; i < 10; i++)
    60             {
    61                 Thread t = new Thread(new ThreadStart(acc.DoTransactions));
    62                 threads[i] = t;
    63             }
    64             for (int i = 0; i < 10; i++)
    65             {
    66                 threads[i].Start();
    67             }
    68         }
    69     }
            
  • 相关阅读:
    如何编写一个有效的缓存
    [深入Maven源代码]maven绑定命令行参数到具体插件
    java.util.ServiceLoader的用法
    非阻塞算法-栈
    非阻塞算法-简单的计数器
    Excelbatis-一个将excel文件读入成实体列表、将实体列表解析成excel文件的ORM框架,简洁易于配置、可扩展性好
    教你如何迭代地遍历二叉树
    [开源项目]Shell4Win,一个在Windows下执行shell命令的解释器
    [LeetCode]Single Number II
    CAS5.3服务环境搭建
  • 原文地址:https://www.cnblogs.com/lewisli/p/3586463.html
Copyright © 2011-2022 走看看