• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >C#教程 > C#中lock死锁实例教程

C#中lock死锁实例教程

作者: 字体:[增加 减小] 来源:互联网 时间:2017-05-28

通过本文主要向大家介绍了c lock 死锁,c#死锁,c#线程死锁,c#多线程死锁,sql 死锁实例等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

在c#中有个关键字lock,它的作用是锁定某一代码块,让同一时间只有一个线程访问该代码块,本文就来谈谈lock关键字的原理和其中应注意的几个问题:

lock的使用原型是:

lock(X)
{
  //需要锁定的代码.... 
}

</div>

首先要明白为什么上面这段话能够锁定代码,其中的奥妙就是X这个对象,事实上X是任意一种引用类型,它在这儿起的作用就是任何线程执行到lock(X)时候,X需要独享才能运行下面的代码,若假定现在有3个线程A,B,C都执行到了lock(X)而ABC因为此时都占有X,这时ABC就要停下来排个队,一个一个使用X,从而起到在下面的代码块内只有一个线程在运行(因为此时只有一个线程独享X,其余两个在排队),所以这个X必须是所有要执行临界区域代码进程必须共有的一个资源,从而起到抑制线程的作用。

下面再来谈谈lock使用中会遇到和注意的问题,lock最需要注意的一个问题就是线程死锁!

在MSDN上列出了3个典型问题:

通常,应避免锁定 public 类型,否则实例将超出代码的控制范围。常见的结构 lock (this)、lock (typeof (MyType)) 和 lock ("myLock") 违反此准则:

如果实例可以被公共访问,将出现 lock (this) 问题。

如果 MyType 可以被公共访问,将出现 lock (typeof (MyType)) 问题。

由于进程中使用同一字符串的任何其他代码将共享同一个锁,所以出现 lock(“myLock”) 问题。

最佳做法是定义 private 对象来锁定, 或 private shared 对象变量来保护所有实例所共有的数据。

(1)lock (this) 问题:

假定有两个类:

class A{} 
class B{} 
</div>

有两个公共对象:

A a=new A(); 
B b=new B(); 
</div>

首先在A中若有一函数内的代码需要锁定:

代码1:

lock(this)//this在这里就是a 
{ 
 //.... 
 lock(b) 
 { 
//...... 
 } 
} 
</div>

然而此时B中某函数也有如下代码需要锁定:

代码2:

lock(this)//this在这里就是b 
{ 
 //.... 
 lock(a) 
 { 
//...... 
 } 
} 
</div>

设想一下上面两段代码在两个线程下同时执行会有什么后果?

结果就是,代码1执行到lock(this)后a被锁定,代码2执行到lock(this)后b被锁定,然后代码1需求b,代码2需求a,此时两个需求都被相互占有出现僵持状态,程序死锁了。

(2)lock(typeof (MyType))问题:

假定有两个公共变量:

int a;float b; 

</div>

下面看如下代码

代码3:

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

</div>

又有如下代码:

代码4:

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

</div>

若有两个进程分别同时进入上面两个代码外层的lock,就分别锁定了System.type.Int和System.type.Float,而马上它们又需求System.type.Float和System.type.Int,彼此相互占有,彼此僵持,程序进入死锁状态!

(3)字符串问题 :

在阐述这个问题之前,有一个知识大家必须知道:C#中字符串被公共语言运行库 (CLR)“暂留”。这意味着整个程序中任何给定字符串都只有一个实例,就是这同一个对象表示了所有运行的应用程序域的所有线程中的该文本。因此,只要在应用程序进程中的任何位置处具有相同内容的字符串上放置了锁,就将锁定应用程序中该字符串的所有实例。

言下之意就是假定有两个类分别有两个字符串:

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

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

</div>

事实上a和c引用的是同一个字符串"abc",b和d引用的是同一个字符串"def"

现在如果在两个类中有如下代码

在类A中有代码5:

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

在类B中有代码6:

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

那么代码5和代码6同时有两个线程执行结果可想而知:在两个线程执行到外层lock代码时"def"和"abc"被锁定。接着他们在内部lock处同时需求"abc"和"def",而此时两个字符串被两个进程彼此占有,程序又死锁了!所以MSDN说:锁定字符串尤其危险!最好不要使用!

MSDN最后说了:最佳做法是定义 private 对象来锁定, 或 private shared 对象变量来保护所有实例所共有的数据。
在个人看来,也不是绝对安全,这里就举出一个例子:

假定有一个类:

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) 
    { 
     //.... 
    } 
  } 
 } 
} 
</div>

现在假定有两个线程同时执行函数x()和y();结果private对象a和b分别在外层lock锁定,接着两个线程在内部又立马需求b和a,a,b彼此占有又彼此需求,程序死锁。

所以具体要看情况而定,但是定义 private 对象来锁定至少可以降低风险。

希望本文所述C#中lock的应用对大家的C#程序设计有所帮助。

</div>
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • C#中lock死锁实例教程

相关文章

  • 2017-05-28C#画圆角矩形的方法
  • 2017-05-28基于字符集、字符编码与HTTP编码解码之万象详解
  • 2017-05-28c#制作屏幕保护程序步骤(字幕屏保)
  • 2017-05-28深入多线程之:深入生产者、消费者队列分析
  • 2017-05-28C#完成word文档打印的方法
  • 2017-05-28C#数组排序的两种常用方法
  • 2017-05-28C#中数组段用法实例分析
  • 2017-05-28C#生成随机ArrayList的方法
  • 2017-05-28c# 开机启动项的小例子
  • 2017-05-28c#中禁用windows的任务管理器的方法

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • C#中Override关键字和New关键字的用法详解
    • C#网络适配器简单操作
    • c#求两个数中最大值的方法
    • C#隐式/显示实现接口方法详解
    • winform调用javascript的小例子
    • c#基础学习之封装
    • C#验证码识别类完整实例
    • WPF 自定义雷达图开发实例教程
    • C#窗体布局方式详解
    • C#实现语音视频录制-附demo源码

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有