• C#多线程lock的使用【转】


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

    1. public class AccessControl()
    2. {
    3. private static object privateObjectLock = new object();
    4. public static AccessResult()
    5.  {
    6. lock(privateObjectLock)
    7. {
    8. //数据操作语句
    9. }
    10. }
    11. }

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

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

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

    1. class EmailInfo
    2. {
    3. public static int CurrentNumber;
    4. }

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

    _CurrentNumber=++EmailInfo.CurrentNumber;

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

    EmialInfo.CurrentNumber加1--EmailInfo.CurrentNumber返回值给_CurrentNumber,也许线程1执行了EmailInfo.CurrentNumber加1
    的操作,但还没有取得返回值,此时线程2又执行了EmailInfo.CurrentNumber加1的操作,然后又线程1,线程2取得了返回值就是一样的,这样就失去了按顺序递增的作用。

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

    1. lock(this)
    2. {
    3. _CurrentNumber=++EmailInfo.CurrentNumber;
    4. }

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

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

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

    先为EmailInfo加一个静态变量

    1. class EmailInfo
    2. {
    3. public static object syncRoot = new object();
    4. public static int CurrentNumber;
    5. } 然后lock改为
    6. lock(EmailInfo.syncRoot)
    7. {
    8. _CurrentNumber=++EmailInfo.CurrentNumber;
    9. }

    即可实现想要的效果了。这样,就解决了C#多线程学习过程中遇到的lock的用法问题。

  • 相关阅读:
    关于桌面的图片打开很慢的解决方法
    用c#进行递归组合
    ajax,js,css 入门页面
    择日宣判此案,却常再无下文
    共享软件的明确定义
    [转]大逃亡,还没出来呢
    如何收集带有附件的网页
    送一份自家产的软件给园内的兄弟姐妹作“福利”
    [转]评蒙牛内幕
    蓝侠==la*uan,破解中国共享软件联盟著名灌水专家“蓝侠””
  • 原文地址:https://www.cnblogs.com/hnsdwhl/p/2025345.html
Copyright © 2020-2023  润新知