c# 中多线程同步Lock的用法

   

临界区(Critical Section)

  是一段在同一时候只被一个线程进入/执行的代码。为啥要有这个东西?

  1. 是因为这段代码访问了“临界资源”,而这种资源只能同时被互斥地访问。举个例子来说,你的银行账户就是一个互斥资源,一个银行系统里面改变余额(存取)的操作代码就必须用在临界区内。如果你的账户余额是$100,000(如果是真的,那么你就不用再往下看了,还是睡觉去吧),假设有两个人同时给你汇款$50,000。有两个线程分别执行这两笔汇款业务,线程A在获取了你的账户余额后,在它把新余额($150000)储存回数据库以前,操作系统把这个线程暂停转而把CPU的时间片分给另一个线程(是的,这太巧了);那么线程B此时取出的账户余额仍然是$10000,随后线程B幸运的得到的CPU时间把$50000存入你的账户,那么余额变成$150000。而此后某个时候,线程A再次得以执行,它也把“新”余额$150000更新到系统……于是你的$50000就这么凭空消失了。(此段省去常见到一个示例图,请自行想象)
  2. 是因为OS的多任务调度,其实在原因一里面已经提到。如果OS不支持多任务调度,那么线程A/线程B执行更新余额的操作总是一个接一个进行,那么完全不会有上面的问题了。在多线程的世界里,你必须随时做好你的代码执行过程随时失去控制的准备;你需要好好考虑当代码重新执行的时候,是否可以继续正确的执行。一句话,你的程序段在多线程的世界里,你所写的方法并不是“原子性”的操作。

Lock关键字

  C#提供lock关键字实现临界区,我们经常习惯性使用Lock(this)是不正确的,一般会产生一些列问题,一般的用法是申明一个static 的对象作为lock的锁,如下例

       static private object Locksrf2ImOb = new object();
        private bool srfToImage(string path, string storepath)
        {
            bool reflag = false;
            try
            {
                lock (Locksrf2ImOb)
                {
                    srf2Ique.Enqueue(path);
                    srf2Ique.Enqueue(storepath);
                
                if (srf2IthFlag == false)
                {
                    Thread srf2I = new Thread(new ThreadStart(srf2Ith));
                    srf2IthFlag = true;
                    srf2I.Start();
                }
                }
                reflag = true;
            }
            catch (System.Exception ex)
            {
                reflag = false;
                MessageBox.Show(ex.Message);
            }
            return reflag;
        }

这样就不会出现一些问题了,如果想知道其中比较详细的原因,可参见博客:

http://blog.csdn.net/xwdpepsi/article/details/6327210

   

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值