c#

位置:IT落伍者 >> c# >> 浏览文章

C#多线程中lock的用法


发布日期:2020年06月19日
 
C#多线程中lock的用法

经常碰到同时需要对某个数据进行操作或者对某个文件进行读写操作对于这些操作我们以前往往不能很好的进行处理自从C#语言中引入了lock这个关键字以上问题就比较容易予以解决了下面就是一段简单的代码

public class AccessControl()

{

private static object privateObjectLock = new object();

public static AccessResult()

{

lock(privateObjectLock)

{

//数据操作语句

}

}

}

在做邮箱接收网关的时候遇到了以下的需求要求为每一个邮箱开启一个接收线程从POP服务器上收取然后将邮件存放到统一的FTP服务器上要求邮件按收接顺充从开始顺充编号

我实现的方法为为每个邮箱new出实例然后分别赋给POP邮箱地址用户名密码等参数这里涉及到一个编号同步的问题因为每个接收邮件的线程都是自己执行所以取得编号并且递增这个动作是互斥的

以一个静态变量表示编号如下

class EmailInfo

{

public static int CurrentNumber;

}

那在当前线程取得这个步骤为

CurrentNumber=++EmailInfoCurrentNumber;

虽然此为一句但在计算机运行时却分为多步如下

EmialInfoCurrentNumber加EmailInfoCurrentNumber返回值给_CurrentNumber也许线程执行了EmailInfoCurrentNumber加 的操作但还没有取得返回值此时线程又执行了EmailInfoCurrentNumber加的操作然后又线程线程取得了返回值就是一样的这样就失去了按顺序递增的作用

此时查找了网上有关线程同步的方法其实用lock语句锁住递增的那一段即可而介绍的相关用法为

lock(this)

{

_CurrentNumber=++EmailInfoCurrentNumber;

}

本以为这样就可以成功谁知道还是无效反复查找才发现没弄清楚lock的用法因为网上所讲的资料举的例子比较简单是直接new 出一个对像然后为对像的一个函数创建了多个线程运行所以它的同步只要lock住this即它自己就行了因为此时只有一个实例在运而我是new 出了多个对像lock住每个自己的实例所以当然无效

所以自然想了一个解决方法就lock住相同的一个实例就行了

因为我每个邮件接收线程的参数都是不同的所以还是new出几个实像但lock的方法改为如下

先为EmailInfo加一个静态变量

class EmailInfo

{

public static object syncRoot = new object();

public static int CurrentNumber;

}

然后lock改为

lock(EmailInfosyncRoot)

{

_CurrentNumber=++EmailInfoCurrentNumber;

}

即可实现想要的效果了

上一篇:.NET类型转换器的定制

下一篇:.Net中如何操作IIS的原理分析