C# 多線程中經(jīng)常訪問同一資源可能造成哪些問題
多線程經(jīng)常訪問同一資源可能造成什么問題
競態(tài)條件和死鎖
如果兩個(gè)或多個(gè)線程訪問相同的對象,或者訪問不同步的共享狀態(tài) ,就會(huì)出現(xiàn)競態(tài)條件;
為了避免出現(xiàn)該問題,可以鎖定共享的對象。但是過多的鎖定也會(huì)有麻煩,那就是死鎖;
當(dāng)至少有兩個(gè)線程被掛起,等待對方解除鎖定。由于兩個(gè)線程都在等待對方,就出現(xiàn)了死鎖,線程將無限等下去;
要避免同步問題,最好不要在線程之間共享數(shù)據(jù)。當(dāng)然,這并不總是可行的。如果需要共享數(shù)據(jù),就必須使用同步技術(shù);
確保一次只有一個(gè)線程訪問和改變共享狀態(tài)。注意,同步問題與競態(tài)條件和死鎖有關(guān)。如果不注意這些問題,就很難在應(yīng)用程序中找到問題的原因,因?yàn)榫€程問題是不定期發(fā)生的。
多線程同時(shí)訪問一個(gè)實(shí)例對象時(shí), 可以給進(jìn)程加一把鎖來處理。
lock是確保當(dāng)一個(gè)線程位于代碼的臨界區(qū)時(shí),另一個(gè)線程不進(jìn)入臨界區(qū)。
如果其他線程試圖進(jìn)入鎖定的代碼,則它將一直等待(即被阻止),直到該對象被釋放。
public class Singleton { ? ? private static Singleton instance; ? ? private static readonly object synRoot=new object(); ? ? private Singleton() //改為私有 ? ? { ? ? } ? ? public static Singleton GetInstance() ? ? { ? ? ? ? lock(synRoot) ? ? ? ? { ? ? ? ? ? ? if(instance==null) ? ? ? ? ? ? { ? ? ? ? ? ? ? ? instance=new Singleton(); ? ? ? ? ? ? } ? ? ? ? ? ? return instance; ? ? ? ? } ? ? } }
雙重鎖定:不用讓線程每次都加鎖,而只是在實(shí)例未被創(chuàng)建的時(shí)候再加鎖處理,提高了性能。
public class Singleton { ? ? private static Singleton instance; ? ? private static readonly object synRoot=new object(); ? ? private Singleton() //改為私有 ? ? { ? ? } ? ? public static Singleton GetInstance() ? ? { ? ? ? ? if(instance==null) ? ? ? ? { ? ? ? ? ? ?lock(synRoot) ? ? ? ? ? ? { ? ? ? ? ? ? ? ? if(instance==null) ? ? ? ? ? ? ? ? { ? ? ? ? ? ? ? ? ? ? instance=new Singleton(); ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? return instance; ? ? ? ? ? ? } ? ? ? ? } ? ? } }
多線程訪問資源沖突問題
多線程訪問同一資源時(shí),可以用同步機(jī)制解決問題
private Object _lock = new Object();//定義一個(gè)對象 private void method( paramtype,paramvalue) //線程訪問方法名 { lock (_lock) { //沖突代碼 } }
1. _lock 被lock了嗎?沒有則由當(dāng)前線程來lock,否則一直等待,直至_lock 被釋放。
2. lock以后在執(zhí)行l(wèi)ock{}中的代碼期間其他線程不能調(diào)用lock{}{中的代碼,也不能使用_lock。
3. 執(zhí)行完lock{}中的代碼之后釋放_(tái)lock,并且lock{}中的代碼可以被其他線程訪問。
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
C#/.Net 中快速批量給SQLite數(shù)據(jù)庫插入測試數(shù)據(jù)
這篇文章主要介紹了C#/.Net 中快速批量給SQLite數(shù)據(jù)庫插入測試數(shù)據(jù),本文直接給出實(shí)例代碼,需要的朋友可以參考下2015-06-06UGUI實(shí)現(xiàn)隨意調(diào)整Text中的字體間距
這篇文章主要為大家詳細(xì)介紹了UGUI實(shí)現(xiàn)隨意調(diào)整字體間距的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-03-03詳解WPF雙滑塊控件的使用和強(qiáng)制捕獲鼠標(biāo)事件焦點(diǎn)
這篇文章主要為大家詳細(xì)介紹了WPF中雙滑塊控件的使用和強(qiáng)制捕獲鼠標(biāo)事件焦點(diǎn)的實(shí)現(xiàn),文中的示例代碼講解詳細(xì),感興趣的可以嘗試一下2022-07-07c#之圓形無標(biāo)題欄橢圓窗體的實(shí)現(xiàn)詳解
本篇文章是對c#中圓形無標(biāo)題欄橢圓窗體的實(shí)現(xiàn)方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-06-06C#事件處理和委托event delegate實(shí)例簡述
這篇文章主要介紹了C#事件處理和委托event delegate的簡單實(shí)例,較為詳細(xì)的講述了C#事件處理和委托的聲明與實(shí)現(xiàn)過程,代碼簡單易懂,需要的朋友可以參考下2014-09-09