亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

C#線程同步方法匯總

2019-11-17 02:23:40
字體:
來源:轉載
供稿:網友
C#線程同步方法匯總

 我們在編程的時候,有時會使用多線程來解決問題,比如你的程序需要在 后臺處理一大堆數據,但還要使用戶界面處于可操作狀態;或者你的程序需要訪問一些外部資源如數據庫或網絡文件等。這些情況你都可以創建一個子線程去處理, 然而,多線程不可避免地會帶來一個問題,就是線程同步的問題。如果這個問題處理不好,我們就會得到一些非預期的結果。

  在網上也看過一些關于線程同步的文章,其實線程同步有好幾種方法,下面我就簡單的做一下歸納。

  一、volatile關鍵字

  volatile是最簡單的一種同步方法,當然簡單是要付出代價的。它只能在變量一級做同步,volatile的含義就是告訴處理器, 不要將我放入工作內存, 請直接在主存操作我。(【轉自www.bitsCN.com】)因此,當多線程同時訪問該變量時,都將直接操作主存,從本質上做到了變量共享。

  能夠被標識為volatile的必須是以下幾種類型:(摘自MSDN)

  • Any reference type.
  • Any pointer type (in an unsafe context).
  • The types sbyte, byte, short, ushort, int, uint, char, float, bool.
  • An enum type with an enum base type of byte, sbyte, short, ushort, int, or uint.

      如:

    Code publicclassA { PRivatevolatileint_i; publicintI { get{return_i; } set{ _i=value; } } }

      但volatile并不能實現真正的同步,因為它的操作級別只停留在變量級別,而不是原子級別。如果是在單處理器系統中,是沒有任何問題的,變量在主存中沒有機會被其他人修改,因為只有一個處理器,這就叫作processor Self-Consistency。但在多處理器系統中,可能就會有問題。每個處理器都有自己的data cach,而且被更新的數據也不一定會立即寫回到主存。所以可能會造成不同步,但這種情況很難發生,因為cach的讀寫速度相當快,flush的頻率也相當高,只有在壓力測試的時候才有可能發生,而且幾率非常非常小。

      二、lock關鍵字

      lock是一種比較好用的簡單的線程同步方式,它是通過為給定對象獲取互斥鎖來實現同步的。它可以保證當一個線程在關鍵代碼段的時候,另一個線程不會進來,它只能等待,等到那個線程對象被釋放,也就是說線程出了臨界區。用法:

    Code publicvoidFunction() { objectlockThis=newobject(); lock(lockThis) { //access thread-sensitive resources. } }

      lock的參數必須是基于引用類型的對象,不要是基本類型像 bool,int什么的,這樣根本不能同步,原因是lock的參數要求是對象,如果傳入int,勢必要發生裝箱操作,這樣每次lock的都將是一個新的不 同的對象。最好避免使用public類型或不受程序控制的對象實例,因為這樣很可能導致死鎖。特別是不要使用字符串作為lock的參數,因為字符串被 CLR“暫留”,就是說整個應用程序中給定的字符串都只有一個實例,因此更容易造成死鎖現象。建議使用不被“暫留”的私有或受保護成員作為參數。其實某些 類已經提供了專門用于被鎖的成員,比如Array類型提供SyncRoot,許多其它集合類型也都提供了SyncRoot。

      所以,使用lock應該注意以下幾點: 

     ?。薄⑷绻粋€類的實例是public的,最好不要lock(this)。因為使用你的類的人也許不知道你用了lock,如果他new了一個實例,并且對這個實例上鎖,就很容易造成死鎖。

     ?。病⑷绻鸐yType是public的,不要lock(typeof(MyType))

     ?。场⒂肋h也不要lock一個字符串

      三、System.Threading.Interlocked

      對于整數數據類型的簡單操作,可以用Interlocked類的成員來實現線程同步,存在于System.Threading命名空間。Interlocked類有以下方法:Increment,Decrement,Exchange和CompareExchange。使用Increment和Decrement可以保證對一個整數的加減為一個原子操作。Exchange方法自動交換指定變量的值。CompareExchange方法組合了兩個操作:比較兩個值以及根據比較的結果將第三個值存儲在其中一個變量中。比較和交換操作也是按原子操作執行的。如:

    Code inti=0; System.Threading.Interlocked.Increment(refi); Console.WriteLine(i); System.Threading.Interlocked.Decrement(refi); Console.WriteLine(i); System.Threading.Interlocked.Exchange(refi,100); Console.WriteLine(i); System.Threading.Interlocked.CompareExchange(refi,10,100);

    Output:

      四、Monitor

      Monitor類提供了與lock類似的功能,不過與lock不同的是,它 能更好的控制同步塊,當調用了Monitor的Enter(Object o)方法時,會獲取o的獨占權,直到調用Exit(Object o)方法時,才會釋放對o的獨占權,可以多次調用Enter(Object o)方法,只需要調用同樣次數的Exit(Object o)方法即可,Monitor類同時提供了TryEnter(Object o,[int])的一個重載方法,該方法嘗試獲取o對象的獨占權,當獲取獨占權失敗時,將返回false。

      但使用lock通常比直接使用Monitor更可取,一方面是因為lock更簡潔,另一方面是因為lock確保了即使受保護的代碼引發異常,也可以釋放基礎監視器。這是通過finally中調用Exit來實現的。事實上,lock就是用Monitor類來實現的。下面兩段代碼是等效的:

    Code lock(x) { DoSomething(); }等效于objectobj=(object)x; System.Threading.Monitor.Enter(obj); try { DoSomething(); } finally { System.Threading.Monitor.Exit(obj); }

    關于用法,請參考下面的代碼:

    Code privatestaticobjectm_monitorObject=newobject(); [STAThread] staticvoidMain(string[] args) { Thread thread=newThread(newThreadStart(Do)); thread.Name="Thread1"; Thread thread2=newThread(newThreadStart(Do)); thread2.Name="Thread2"; thread.Start(); thread2.Start(); thread.Join(); thread2.Join(); Console.Read(); } staticvoidDo() { if(!Monitor.TryEnter(m_monitorObject)) { Console.WriteLine("Can't visit Object"+Thread.CurrentThread.Name); return; } try { Monitor.Enter(m_monitorObject); Console.WriteLine("Enter Monitor"+Thread.CurrentThread.Name); Thread.Sleep(5000); } finally { Monitor.Exit(m_monitorObject); } }

      當線程1獲取了m_monitorObject對象獨占權時,線程2嘗試調用TryEnter(m_monitorObject),此時會由于無法獲取獨占權而返回false,輸出信息如下:

      另外,Monitor還提供了三個靜態方法 Monitor.Pulse(Object o),Monitor.PulseAll(Object o)和Monitor.Wait(Object o ) ,用來實現一種喚醒機制的同步。關于這三個方法的用法,可以參考MSDN,這里就不詳述了。

      五、Mutex

      在使用上,Mutex與上述的Monitor比較接近,不過Mutex不具 備Wait,Pulse,PulseAll的功能,因此,我們不能使用Mutex實現類似的喚醒的功能。不過Mutex有一個比較大的特點,Mutex是 跨進程的,因此我們可以在同一臺機器甚至遠程的機器上的多個進程上使用同一個互斥體。盡管Mutex也可以實現進程內的線程同步,而且功能也更強大,但這 種情況下,還是推薦使用Monitor,因為Mutex類是win32封裝的,所以它所需要的互操作轉換更耗資源。

      六、ReaderWriterLock

      在考慮資源訪問的時候,慣性上我們會對資源實施lock機制,但是在某些情 況下,我們僅僅需要讀取資源的數據,而不是修改資源的數據,在這種情況下獲取資源的獨占權無疑會影響運行效率,因此.Net提供了一種機制,使用 ReaderWriterLock進行資源訪問時,如果在某一時刻資源并沒有獲取寫的獨占權,那么可以獲得多個讀的訪問權,單個寫入的獨占權,如果某一時 刻已經獲取了寫入的獨占權,那么其它讀取的訪問權必須進行等待,參考以下代碼:

    Code privatestaticReaderWriterLock m_readerWriterLock=newReaderWriterLock(); privatestaticintm_int=0; [STAThread] staticvoidMain(string[] args) { Thread readThread=newThread(newThreadStart(Read)); readThread.Name="ReadThread1"; Thread readThread2=newThread(newThreadStart(Read)); readThread2.Name="ReadThread2"; Thread writeThread=newThread(newThreadStart(Writer)); writeThread.Name="WriterThread"; readThread.Start(); readThread2.Start(); writeThread.Start(); readThread.Join(); readThread2.Join(); writeThread.Join();Console.ReadLine();
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
日韩激情视频在线| 久久99精品久久久久久青青91| 4438全国亚洲精品在线观看视频| 欧美中文字幕视频在线观看| 国产日韩在线播放| 日韩a**中文字幕| 欧美成人精品一区二区三区| 午夜精品久久久久久久白皮肤| 亚洲第一色中文字幕| 亚洲白拍色综合图区| 日韩一区二区三区在线播放| 中文字幕久久亚洲| 国产视频观看一区| 性夜试看影院91社区| 欧美国产日本在线| 国产第一区电影| 日韩欧美国产网站| 黄色一区二区在线| 精品欧美国产一区二区三区| 中文字幕av日韩| 国产精品高潮呻吟久久av黑人| 日韩中文字幕久久| 国产日韩欧美视频在线| 日韩av免费网站| 欧美福利在线观看| 美女999久久久精品视频| 精品久久香蕉国产线看观看亚洲| 日韩精品在线第一页| 久久亚洲精品视频| 久久免费高清视频| 国产成人91久久精品| 日韩精品福利在线| 5278欧美一区二区三区| 欧美老女人www| 欧洲永久精品大片ww免费漫画| 日韩电影在线观看永久视频免费网站| 成人黄色免费片| 国产精品免费电影| 成人黄色大片在线免费观看| 久久影视三级福利片| 亚洲免费精彩视频| 久久久国产在线视频| 色婷婷综合成人| 亲爱的老师9免费观看全集电视剧| 91人人爽人人爽人人精88v| 在线观看视频99| 国产精品入口夜色视频大尺度| 免费不卡在线观看av| 性色av一区二区三区红粉影视| 2019中文字幕全在线观看| 久久久久久这里只有精品| 国产精品自产拍在线观看中文| 欧洲永久精品大片ww免费漫画| 亚洲国产小视频在线观看| 色综合久久久久久中文网| 国产日韩欧美在线看| 欧美成人午夜剧场免费观看| 国产精品最新在线观看| 亚洲精品99999| 国产免费一区二区三区香蕉精| 欧美老妇交乱视频| 国产精品入口夜色视频大尺度| 久久国产精品99国产精| 午夜精品久久久99热福利| 久久久免费精品视频| 日韩精品中文字幕在线观看| 成人www视频在线观看| 日韩美女视频中文字幕| 在线a欧美视频| 久久国产精品网站| 欧美国产视频日韩| 久久人91精品久久久久久不卡| 国内外成人免费激情在线视频| 不卡av电影在线观看| 欧美高清在线视频观看不卡| 欧美高清在线播放| 亚洲成人精品久久久| 国产精品视频永久免费播放| 在线电影中文日韩| 97不卡在线视频| 91探花福利精品国产自产在线| 国产一区二区三区在线播放免费观看| 成人观看高清在线观看免费| 91久久国产精品91久久性色| 日本精品免费一区二区三区| 自拍视频国产精品| 日韩三级影视基地| 亚洲天堂精品在线| 国产日韩亚洲欧美| 中文字幕一区二区三区电影| 欧美第一淫aaasss性| 久久亚洲欧美日韩精品专区| 国产主播在线一区| 国产91在线播放九色快色| 尤物yw午夜国产精品视频明星| 久久久国产影院| 日本高清不卡在线| 国产91精品黑色丝袜高跟鞋| 国产精品久久久久91| 午夜精品一区二区三区av| 国产性猛交xxxx免费看久久| 日韩在线观看高清| 国产视频久久久久| 日韩亚洲国产中文字幕| 亚洲精品视频久久| 亚洲理论在线a中文字幕| 亚洲欧美中文字幕在线一区| 中文字幕日韩视频| 久久综合国产精品台湾中文娱乐网| 国语自产精品视频在线看抢先版图片| 4438全国亚洲精品在线观看视频| 欧洲亚洲免费在线| 日韩免费在线电影| 中文字幕在线视频日韩| www.美女亚洲精品| 亚洲一区二区三区四区在线播放| 狠狠操狠狠色综合网| 亚洲国产欧美一区二区三区同亚洲| 成人激情视频网| 成人网址在线观看| 欧美日韩一区二区三区在线免费观看| 久久6免费高清热精品| 日韩中文字幕在线视频| 中文字幕精品久久| 亚洲国产日韩欧美在线99| 国产国语videosex另类| 日韩精品在线观看一区二区| 久久久精品欧美| 久久久久久亚洲精品| 久久久久久中文| 欧美成人精品h版在线观看| 国产精品久久久久91| 欧美激情一二区| 91在线视频一区| 亚洲一区二区久久久久久久| 国产一区二区三区欧美| 爽爽爽爽爽爽爽成人免费观看| 动漫精品一区二区| 日本一欧美一欧美一亚洲视频| 亚洲精品福利免费在线观看| 成人www视频在线观看| 中文字幕亚洲无线码在线一区| 欧美猛交ⅹxxx乱大交视频| 美女视频久久黄| 欧美国产日韩在线| 亚洲第一视频网| 亚洲成人a**站| 国产专区精品视频| 九九热最新视频//这里只有精品| 日韩精品极品在线观看播放免费视频| 国产精品一区二区久久久| 8090成年在线看片午夜| 色琪琪综合男人的天堂aⅴ视频| 国产suv精品一区二区| 国产丝袜一区视频在线观看| 欧美大片欧美激情性色a∨久久| 欧美成人免费在线视频| 国内精品伊人久久| 日韩中文第一页| 欧美福利视频在线观看| 欧美一级电影在线| 在线性视频日韩欧美| 海角国产乱辈乱精品视频| 亚洲黄页网在线观看|