亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

C#中l(wèi)ock死鎖實(shí)例教程

 更新時(shí)間:2014年08月25日 15:46:00   投稿:shichen2014  
這篇文章主要介紹了C#中l(wèi)ock死鎖的用法,對(duì)于共享資源的訪問及C#程序設(shè)計(jì)的安全性而言,有著非常重要的意義!需要的朋友可以參考下

在c#中有個(gè)關(guān)鍵字lock,它的作用是鎖定某一代碼塊,讓同一時(shí)間只有一個(gè)線程訪問該代碼塊,本文就來(lái)談?wù)刲ock關(guān)鍵字的原理和其中應(yīng)注意的幾個(gè)問題:

lock的使用原型是:

lock(X)
{
  //需要鎖定的代碼.... 
}

首先要明白為什么上面這段話能夠鎖定代碼,其中的奧妙就是X這個(gè)對(duì)象,事實(shí)上X是任意一種引用類型,它在這兒起的作用就是任何線程執(zhí)行到lock(X)時(shí)候,X需要獨(dú)享才能運(yùn)行下面的代碼,若假定現(xiàn)在有3個(gè)線程A,B,C都執(zhí)行到了lock(X)而ABC因?yàn)榇藭r(shí)都占有X,這時(shí)ABC就要停下來(lái)排個(gè)隊(duì),一個(gè)一個(gè)使用X,從而起到在下面的代碼塊內(nèi)只有一個(gè)線程在運(yùn)行(因?yàn)榇藭r(shí)只有一個(gè)線程獨(dú)享X,其余兩個(gè)在排隊(duì)),所以這個(gè)X必須是所有要執(zhí)行臨界區(qū)域代碼進(jìn)程必須共有的一個(gè)資源,從而起到抑制線程的作用。

下面再來(lái)談?wù)刲ock使用中會(huì)遇到和注意的問題,lock最需要注意的一個(gè)問題就是線程死鎖!

在MSDN上列出了3個(gè)典型問題:

通常,應(yīng)避免鎖定 public 類型,否則實(shí)例將超出代碼的控制范圍。常見的結(jié)構(gòu) lock (this)、lock (typeof (MyType)) 和 lock ("myLock") 違反此準(zhǔn)則:

如果實(shí)例可以被公共訪問,將出現(xiàn) lock (this) 問題。

如果 MyType 可以被公共訪問,將出現(xiàn) lock (typeof (MyType)) 問題。

由于進(jìn)程中使用同一字符串的任何其他代碼將共享同一個(gè)鎖,所以出現(xiàn) lock(“myLock”) 問題。

最佳做法是定義 private 對(duì)象來(lái)鎖定, 或 private shared 對(duì)象變量來(lái)保護(hù)所有實(shí)例所共有的數(shù)據(jù)。

(1)lock (this) 問題:

假定有兩個(gè)類:

class A{} 
class B{} 

有兩個(gè)公共對(duì)象:

A a=new A(); 
B b=new B(); 

首先在A中若有一函數(shù)內(nèi)的代碼需要鎖定:

代碼1:

lock(this)//this在這里就是a 
{ 
 //.... 
 lock(b) 
 { 
//...... 
 } 
} 

然而此時(shí)B中某函數(shù)也有如下代碼需要鎖定:

代碼2:

lock(this)//this在這里就是b 
{ 
 //.... 
 lock(a) 
 { 
//...... 
 } 
} 

設(shè)想一下上面兩段代碼在兩個(gè)線程下同時(shí)執(zhí)行會(huì)有什么后果?

結(jié)果就是,代碼1執(zhí)行到lock(this)后a被鎖定,代碼2執(zhí)行到lock(this)后b被鎖定,然后代碼1需求b,代碼2需求a,此時(shí)兩個(gè)需求都被相互占有出現(xiàn)僵持狀態(tài),程序死鎖了。

(2)lock(typeof (MyType))問題:

假定有兩個(gè)公共變量:

int a;float b; 

下面看如下代碼

代碼3:

lock(typeof(a))//typeof(a)就是System.type.Int類型 
{ 
 //.... 
 lock(typeof(b)) 
 { 
//...... 
 } 
} 

又有如下代碼:

代碼4:

lock(typeof(b))//typeof(b)就是System.type.Float類型 
{ 
 //.... 
 lock(typeof(a)) 
 { 
//...... 
 } 
} 

若有兩個(gè)進(jìn)程分別同時(shí)進(jìn)入上面兩個(gè)代碼外層的lock,就分別鎖定了System.type.Int和System.type.Float,而馬上它們又需求System.type.Float和System.type.Int,彼此相互占有,彼此僵持,程序進(jìn)入死鎖狀態(tài)!

(3)字符串問題 :

在闡述這個(gè)問題之前,有一個(gè)知識(shí)大家必須知道:C#中字符串被公共語(yǔ)言運(yùn)行庫(kù) (CLR)“暫留”。這意味著整個(gè)程序中任何給定字符串都只有一個(gè)實(shí)例,就是這同一個(gè)對(duì)象表示了所有運(yùn)行的應(yīng)用程序域的所有線程中的該文本。因此,只要在應(yīng)用程序進(jìn)程中的任何位置處具有相同內(nèi)容的字符串上放置了鎖,就將鎖定應(yīng)用程序中該字符串的所有實(shí)例。

言下之意就是假定有兩個(gè)類分別有兩個(gè)字符串:

class A 
{ 
 string a="abc"; 
 string b="def"; 
} 

class c 
{ 
 string c="abc"; 
 string d="def"; 
} 

事實(shí)上a和c引用的是同一個(gè)字符串"abc",b和d引用的是同一個(gè)字符串"def"

現(xiàn)在如果在兩個(gè)類中有如下代碼

在類A中有代碼5:

lock(b)//b是"def" 
{ 
 //.... 
 lock(a)//a是"abc" 
 { 
//...... 
 } 
} 

在類B中有代碼6:

lock(c)//c是"abc" 
{ 
 //.... 
 lock(d)//d是"def" 
 { 
//...... 
 } 
} 

那么代碼5和代碼6同時(shí)有兩個(gè)線程執(zhí)行結(jié)果可想而知:在兩個(gè)線程執(zhí)行到外層lock代碼時(shí)"def"和"abc"被鎖定。接著他們?cè)趦?nèi)部lock處同時(shí)需求"abc"和"def",而此時(shí)兩個(gè)字符串被兩個(gè)進(jìn)程彼此占有,程序又死鎖了!所以MSDN說(shuō):鎖定字符串尤其危險(xiǎn)!最好不要使用!

MSDN最后說(shuō)了:最佳做法是定義 private 對(duì)象來(lái)鎖定, 或 private shared 對(duì)象變量來(lái)保護(hù)所有實(shí)例所共有的數(shù)據(jù)。
在個(gè)人看來(lái),也不是絕對(duì)安全,這里就舉出一個(gè)例子:

假定有一個(gè)類:

class A 
{ 
 private Object a=new Object(); 
 private Object b=new Object(); 
 public void x() 
 { 
  lock(a) 
  { 
    //..... 
    lock(b) 
    { 
     //.... 
    } 
  } 
 } 
 public void y() 
 { 
  lock(b) 
  { 
    //..... 
    lock(a) 
    { 
     //.... 
    } 
  } 
 } 
} 

現(xiàn)在假定有兩個(gè)線程同時(shí)執(zhí)行函數(shù)x()和y();結(jié)果private對(duì)象a和b分別在外層lock鎖定,接著兩個(gè)線程在內(nèi)部又立馬需求b和a,a,b彼此占有又彼此需求,程序死鎖。

所以具體要看情況而定,但是定義 private 對(duì)象來(lái)鎖定至少可以降低風(fēng)險(xiǎn)。

希望本文所述C#中l(wèi)ock的應(yīng)用對(duì)大家的C#程序設(shè)計(jì)有所幫助。

相關(guān)文章

  • C#中的where泛型約束介紹

    C#中的where泛型約束介紹

    這個(gè)關(guān)于泛型約束的東西我看了幾天了。一直沒打看懂,我的領(lǐng)悟能力有點(diǎn)差,剛才突然明白了一點(diǎn)
    2013-04-04
  • C#實(shí)現(xiàn)日期格式轉(zhuǎn)換的公共方法類實(shí)例

    C#實(shí)現(xiàn)日期格式轉(zhuǎn)換的公共方法類實(shí)例

    這篇文章主要介紹了C#實(shí)現(xiàn)日期格式轉(zhuǎn)換的公共方法類,結(jié)合完整實(shí)例形式分析了C#針對(duì)各種常見日期格式的轉(zhuǎn)換方法,涉及C#字符串、日期、時(shí)間相關(guān)操作技巧,需要的朋友可以參考下
    2017-01-01
  • C#集合之并發(fā)集合的用法

    C#集合之并發(fā)集合的用法

    這篇文章介紹了C#集合之并發(fā)集合的用法,文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-04-04
  • c#讀取文件詳談

    c#讀取文件詳談

    你平時(shí)是怎么讀取文件的?使用流讀取。是的沒錯(cuò),C#給我們提供了非常強(qiáng)大的類庫(kù)(又一次吹捧了.NET一番)
    2013-09-09
  • C#中的那些警告該如何去除(完全去除C#警告)

    C#中的那些警告該如何去除(完全去除C#警告)

    C#(英文名為 CSharp)是微軟開發(fā)的一種面向?qū)ο蟮木幊陶Z(yǔ)言,下面這篇文章主要給大家介紹了關(guān)于C#中的那些警告該如何去除的相關(guān)資料,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2023-02-02
  • c#和net存取cookies操作示例

    c#和net存取cookies操作示例

    這篇文章主要介紹了c#和net存取cookies操作示例,需要的朋友可以參考下
    2014-02-02
  • c# Base關(guān)鍵字的使用

    c# Base關(guān)鍵字的使用

    c# Base關(guān)鍵字的使用示例代碼,大家可以參考下用法。
    2009-07-07
  • C# 設(shè)計(jì)模式系列教程-適配器模式

    C# 設(shè)計(jì)模式系列教程-適配器模式

    通過適配器,客戶端可以調(diào)用同一接口,因而對(duì)客戶端來(lái)說(shuō)是透明的。這樣做更簡(jiǎn)單、更直接、更緊湊。
    2016-06-06
  • C#面向?qū)ο缶幊讨薪涌诟綦x原則的示例詳解

    C#面向?qū)ο缶幊讨薪涌诟綦x原則的示例詳解

    在面向?qū)ο缶幊讨?,SOLID?是五個(gè)設(shè)計(jì)原則的首字母縮寫,旨在使軟件設(shè)計(jì)更易于理解、靈活和可維護(hù)。本文將通過實(shí)例詳細(xì)講講C#面向?qū)ο缶幊讨薪涌诟綦x原則,需要的可以參考一下
    2022-07-07
  • C#控件閃爍的解決方法

    C#控件閃爍的解決方法

    這篇文章主要介紹了C#控件閃爍的解決方法,涉及SetStyle函數(shù)的使用技巧,需要的朋友可以參考下
    2015-01-01

最新評(píng)論