解析使用C# lock同时访问共享数据

所属分类: 软件编程 / C#教程 阅读数: 142
收藏 0 赞 0 分享
经常碰到同时需要对某个数据进行操作,或者对某个文件进行读写操作,对于这些操作我们以前往往不能很好的进行处理,自从C#语言中引入了lock这个关键字,以上问题就比较容易予以解决了,下面就是一段简单的代码。
复制代码 代码如下:

public class AccessControl()
{
    private static object privateObjectLock = new object();
    public static AccessResult()
    {
       lock(privateObjectLock)
       {
         //数据操作语句
       }
    }
}

=====================================================
C#多线程中lock的用法
在做邮箱接收网关的时候遇到了以下的需求,要求为每一个邮箱开启一个接收线程,从POP3服务器上收取,然后将邮件存放到统一的FTP服务器上,要求邮件按收接顺充从1开始顺充编号。
我实现的方法为,为每个邮箱new出实例,然后分别赋给POP3邮箱地址,用户名,密码等参数。这里涉及到一个编号同步的问题,因为每个接收邮件的线程都是自己执行,所以取得编号并且递增这个动作是互斥的。
以一个静态变量表示编号如下
复制代码 代码如下:

class EmailInfo
{
   public static int CurrentNumber;
}

那在当前线程取得这个步骤为
复制代码 代码如下:

_CurrentNumber=++EmailInfo.CurrentNumber;

虽然此为一句,但在计算机运行时却分为多步,如下
EmialInfo.CurrentNumber加1--EmailInfo.CurrentNumber返回值给_CurrentNumber
,也许线程1执行了EmailInfo.CurrentNumber加1 的操作,但还没有取得返回值,此时线程2又执行了EmailInfo.CurrentNumber加1的操作,然后又线程1,线程2取得了返回值就是一样的,这样就失去了按顺序递增的作用。
此时查找了网上有关线程同步的方法,其实用lock语句锁住递增的那一段即可。而介绍的相关用法为
复制代码 代码如下:

lock(this)
{
   _CurrentNumber=++EmailInfo.CurrentNumber;
}

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

所以自然想了一个解决方法,就lock住相同的一个实例就行了。因为我每个邮件接收线程的参数都是不同的,所以还是new出几个实像,但lock的方法改为如下
先为EmailInfo加一个静态变量
复制代码 代码如下:

class EmailInfo
{
   public static object syncRoot = new object();
   public static int CurrentNumber;
}

然后lock改为
复制代码 代码如下:

lock(EmailInfo.syncRoot)
{
   _CurrentNumber=++EmailInfo.CurrentNumber;
}

即可实现想要的效果了。
写出来之后发现原来是件很简单的事,就是lock住一个大家都共同访问的(静态static的)东东就行了,但这个却搞了我很长时间。究其原因对所查资料没有认真理解,拿来就用,以为什么都懂,其实不然。
我想可能有初学者也会犯类似的错误,所以写出来以求共勉。欢迎学习C#或工作中用到C#的朋友与我交流
更多精彩内容其他人还在看

C# 大小写转换(金额)实例代码

C# 大小写转换(金额)实例代码,需要的朋友可以参考一下
收藏 0 赞 0 分享

C# WinForm中Panel实现用鼠标操作滚动条的实例方法

由于在WinForm中Panel不能直接响应鼠标的滚动事件,只好采用捕获窗体的滚动事件。
收藏 0 赞 0 分享

C#访问应用程序配置文件的方法

C#访问应用程序配置文件的方法,需要的朋友可以参考一下
收藏 0 赞 0 分享

C#读写文件的方法汇总

C#读写文件的方法汇总,需要的朋友可以参考一下
收藏 0 赞 0 分享

C#计算代码执行时间的方法

在一些测试工作时我们需要获得高精度的代码执行时间以比较其效率。
收藏 0 赞 0 分享

C# 动画窗体(AnimateWindow)的小例子

C# 动画窗体(AnimateWindow)的小例子,需要的朋友可以参考一下
收藏 0 赞 0 分享

C# zxing二维码写入的实例代码

C# zxing二维码写入的实例代码,需要的朋友可以参考一下
收藏 0 赞 0 分享

c#判断输入的是不是数字的小例子

c#判断输入的是不是数字的小例子,需要的朋友可以参考一下
收藏 0 赞 0 分享

c# 深拷贝与浅拷贝的区别分析及实例

浅拷贝(影子克隆):只复制对象的基本类型,对象类型,仍属于原来的引用. 深拷贝(深度克隆):不紧复制对象的基本类,同时也复制原对象中的对象.就是说完全是新对象产生的.
收藏 0 赞 0 分享

C#利用com操作excel释放进程的解决方法

最近利用Microsoft.Office.Interop.Excel.Application读取一个excel后,进程中一直存在excel,在网上找了一阵子,其中有几个解决方案
收藏 0 赞 0 分享
查看更多