最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C#使用LOCK實(shí)現(xiàn)線程同步

 更新時(shí)間:2022年04月19日 16:51:15   作者:農(nóng)碼一生  
這篇文章介紹了C#使用LOCK實(shí)現(xiàn)線程同步的方法,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

一、簡介

線程安全概念:線程安全是指在當(dāng)一個(gè)線程訪問該類的某個(gè)數(shù)據(jù)時(shí),進(jìn)行保護(hù),其他線程不能進(jìn)行訪問直到該線程讀取完,其他線程才可使用。不會(huì)出現(xiàn)數(shù)據(jù)不一致或者數(shù)據(jù)污染。

線程有可能和其他線程共享一些資源,比如,內(nèi)存,文件,數(shù)據(jù)庫等。當(dāng)多個(gè)線程同時(shí)讀寫同一份共享資源的時(shí)候,可能會(huì)引起沖突。這時(shí)候,我們需要引入線程“同步”機(jī)制,即各位線程之間要有個(gè)先來后到,不能一窩蜂擠上去搶作一團(tuán)。線程同步的真實(shí)意思和字面意思恰好相反。線程同步的真實(shí)意思,其實(shí)是“排隊(duì)”:幾個(gè)線程之間要排隊(duì),一個(gè)一個(gè)對共享資源進(jìn)行操作,而不是同時(shí)進(jìn)行操作。

二、代碼

下面將通過簡單的四個(gè)案例進(jìn)行對比,來講解LOCK的實(shí)現(xiàn)線程同步使用。

案例一:

首先創(chuàng)建兩個(gè)線程,兩個(gè)線程執(zhí)行同一個(gè)方法,代碼如下:

class Program
    {
        static void Main(string[] args)
        {
            Thread threadA = new Thread(ThreadMethod); //執(zhí)行的必須是無返回值的方法 
            threadA.Name = "threadA";
            Thread threadB = new Thread(ThreadMethod); //執(zhí)行的必須是無返回值的方法 
            threadB.Name = "threadB";
            threadA.Start();
            threadB.Start();
            Console.ReadKey();
        }
        public static void ThreadMethod(object parameter)
        {
            for (int i = 1; i <= 10; i++)
            {
                Console.WriteLine("我是:{0},我循環(huán){1}次", Thread.CurrentThread.Name, i);
                Thread.Sleep(1000);//休眠一秒
            }
        }
    }

通過下面的執(zhí)行結(jié)果,可以很清楚的看到,兩個(gè)線程是在同時(shí)執(zhí)行ThreadMethod這個(gè)方法,這顯然不符合我們線程同步的要求。

執(zhí)行結(jié)果:

案例二:

通過對上面代碼的修改如下:

class Program
    {
        static void Main(string[] args)
        {
            Program pro = new Program();
            Thread threadA = new Thread(pro.ThreadMethod); 
            threadA.Name = "threadA";
            Thread threadB = new Thread(pro.ThreadMethod); 
            threadB.Name = "threadB";
            threadA.Start();
            threadB.Start();
            Console.ReadKey();
        }
        public void ThreadMethod(object parameter)
        {
            lock (this) //添加lock關(guān)鍵字
            {
                for (int i = 1; i <= 10; i++)
                {
                    Console.WriteLine("我是:{0},我循環(huán){1}次", Thread.CurrentThread.Name, i);
                    Thread.Sleep(1000);//休眠一秒
                }
            }
        }
    }

執(zhí)行結(jié)果:

 

我們通過添加了 lock(this) {...}代碼,查看執(zhí)行結(jié)果實(shí)現(xiàn)了我們想要的線程同步需求。

案例三:

但是我們知道this表示當(dāng)前類實(shí)例的本身,那么有這么一種情況,我們把需要訪問的方法所在的類型進(jìn)行兩個(gè)實(shí)例A和B,線程A訪問實(shí)例A的方法ThreadMethod,線程B訪問實(shí)例B的方法ThreadMethod,這樣的話還能夠達(dá)到線程同步的需求嗎?

修改后的代碼如下:

class Program
    {
        static void Main(string[] args)
        {
            Program pro1 = new Program();
            Program pro2 = new Program();
            Thread threadA = new Thread(pro1.ThreadMethod); 
            threadA.Name = "threadA";
            Thread threadB = new Thread(pro2.ThreadMethod); 
            threadB.Name = "threadB";
            threadA.Start();
            threadB.Start();
            Console.ReadKey();
        }
        public void ThreadMethod(object parameter)
        {
            lock (this) //添加lock關(guān)鍵字
            {
                for (int i = 1; i <= 10; i++)
                {
                    Console.WriteLine("我是:{0},我循環(huán){1}次", Thread.CurrentThread.Name, i);
                    Thread.Sleep(1000);//休眠一秒
                }
            }
        }
    }

執(zhí)行結(jié)果:

我們會(huì)發(fā)現(xiàn),線程又沒有實(shí)現(xiàn)同步了!lock(this)對于這種情況是不行的!

案例四:

通過對上面代碼再次進(jìn)行如下修改:

class Program
    {
        private static object obj = new object();
        static void Main(string[] args)
        {
            Program pro1 = new Program();
            Program pro2 = new Program();
            Thread threadA = new Thread(pro1.ThreadMethod); 
            threadA.Name = "threadA";
            Thread threadB = new Thread(pro2.ThreadMethod); 
            threadB.Name = "threadB";
            threadA.Start();
            threadB.Start();
            Console.ReadKey();
        }
        public void ThreadMethod(object parameter)
        {
            lock (obj) //添加lock關(guān)鍵字
            {
                for (int i = 1; i <= 10; i++)
                {
                    Console.WriteLine("我是:{0},我循環(huán){1}次", Thread.CurrentThread.Name, i);
                    Thread.Sleep(1000);//休眠一秒
                }
            }
        }
    }

執(zhí)行結(jié)果:

通過查看執(zhí)行結(jié)果。會(huì)發(fā)現(xiàn)代碼實(shí)現(xiàn)了我們的需求。

那么 lock(this) 和lock(Obj)有什么區(qū)別呢?

lock(this) 鎖定 當(dāng)前實(shí)例對象,如果有多個(gè)類實(shí)例的話,lock鎖定的只是當(dāng)前類實(shí)例,對其它類實(shí)例無影響。所有不推薦使用。
lock(typeof(Model))鎖定的是model類的所有實(shí)例。
lock(obj)鎖定的對象是全局的私有化靜態(tài)變量。外部無法對該變量進(jìn)行訪問。
lock 確保當(dāng)一個(gè)線程位于代碼的臨界區(qū)時(shí),另一個(gè)線程不進(jìn)入臨界區(qū)。如果其他線程試圖進(jìn)入鎖定的代碼,則它將一直等待(即被阻止),直到該對象被釋放。
所以,lock的結(jié)果好不好,還是關(guān)鍵看鎖的誰,如果外邊能對這個(gè)誰進(jìn)行修改,lock就失去了作用。所以一般情況下,使用私有的、靜態(tài)的并且是只讀的對象

三、總結(jié)

  • 1.lock的是必須是引用類型的對象,string類型除外。
  • 2.lock推薦的做法是使用靜態(tài)的、只讀的、私有的對象。
  • 3.保證lock的對象在外部無法修改才有意義,如果lock的對象在外部改變了,對其他線程就會(huì)暢通無阻,失去了lock的意義。

不能鎖定字符串,鎖定字符串尤其危險(xiǎn),因?yàn)樽址还舱Z言運(yùn)行庫 (CLR)“暫留”。 這意味著整個(gè)程序中任何給定字符串都只有一個(gè)實(shí)例,就是這同一個(gè)對象表示了所有運(yùn)行的應(yīng)用程序域的所有線程中的該文本。因此,只要在應(yīng)用程序進(jìn)程中的任何位置處具有相同內(nèi)容的字符串上放置了鎖,就將鎖定應(yīng)用程序中該字符串的所有實(shí)例。通常,最好避免鎖定 public 類型或鎖定不受應(yīng)用程序控制的對象實(shí)例。例如,如果該實(shí)例可以被公開訪問,則 lock(this) 可能會(huì)有問題,因?yàn)椴皇芸刂频拇a也可能會(huì)鎖定該對象。這可能導(dǎo)致死鎖,即兩個(gè)或更多個(gè)線程等待釋放同一對象。出于同樣的原因,鎖定公共數(shù)據(jù)類型(相比于對象)也可能導(dǎo)致問題。而且lock(this)只對當(dāng)前對象有效,如果多個(gè)對象之間就達(dá)不到同步的效果。lock(typeof(Class))與鎖定字符串一樣,范圍太廣了。

到此這篇關(guān)于C#使用LOCK實(shí)現(xiàn)線程同步的文章就介紹到這了。希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評論

湖南省| 绥宁县| 桂阳县| 聊城市| 金坛市| 长岭县| 沧源| 临泽县| 慈溪市| 聂拉木县| 常山县| 大余县| 兖州市| 平定县| 阿拉善左旗| 始兴县| 鹤庆县| 门头沟区| 扶绥县| 丁青县| 建始县| 宝坻区| 莎车县| 镇康县| 元朗区| 且末县| 兴文县| 江山市| 绿春县| 饶河县| 崇明县| 拉孜县| 兰西县| 聂拉木县| 阳泉市| 揭西县| 富川| 昌平区| 祁阳县| 绥江县| 家居|