C#的Lock


有時候在編寫線程並發的時候需要考慮異步和同步的問題。有些資源只能是一個線程訪問,其他的線程在這個線程沒有釋放資源前不能訪問。類似於操作系統中臨界資源的訪問。C#Lock包裹的代碼塊具有原子操作的特性(要么執行到結束為止,要么不執行)。

舉個列子:銀行賬戶的余額就是典型的臨界資源的問題,假如原本有1000,你的情婦A,B先后打500給你。A打500的這個操作是一個線程,從數據庫取出余額的值累加正准備寫回數據庫的時候,由於某種原因(時間片用完、來了更高的優先級的線程)阻塞,這時候B又給你打500,他得到余額依然是1000,累加后寫回數據庫1500到手。這時剛才被阻塞的線程又獲得執行權,將1500寫回數據庫。你莫名奇妙少了500,回去找情婦理論是沒有結果的,銀行系統的鍋。

Lock可以運用在單列模式上。剛開始我一直納悶Lock括號里面究竟寫什么,經同學指點。大概是任意不會改變的對象(里面寫一個固定的字符串”999“也可以)

那個對象是一把鎖。它會把鑰匙給第一個訪問它的進程,如果進程完事就上交鑰匙。有且只有一把鑰匙,實現了原子操作

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

namespace TestLock
{
    class TestThread
    {
        private static TestThread instance;
        private static Object obj = new object();
        private TestThread() { }

        public static void GetInstance()
        {
            if (instance == null)//先判斷,異步
            {
               lock (obj)//任意不改變對象
                {
                    if (instance == null)//同步
                    {
                        Console.WriteLine("初始化");
                        instance = new TestThread();
                    }
                }
             }
         }
    }
}

  

Thread t1 = new Thread(TestThread.GetInstance);
Thread t2 = new Thread(TestThread.GetInstance);
Thread t3 = new Thread(TestThread.GetInstance);
t1.Start();
t2.Start();
t3.Start();

  結果是只打印一行初始化,如果沒有lock包裹那塊代碼那么結果會有三行初始化。因為,線程都會遇到if (instance == null)真


免責聲明!

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



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