线程锁

使用线程锁的体会:

多线程的使用已经很普及,但是在使用多线程时,一定要注意安全,比如:多个线程能够同时访问同一个变量时,要注意这个共同变量的资源分配策略。

通常情况下是为其【加锁】,加锁也即创建临界区,也就是当一个线程访问一段代码时,将这段代码进行锁定。但,实际理解起来并不是很简单,创建临界区在C#中使用lock关键字来锁定一段代码。

如:lock(object){操作....实际要控制并发线程要访问的公共变量}

要想真正实现代码段加锁,如上代码的object对象很重要,对于object的定义规则:

  • object必须是引用类型,但还不能是string,因为系统给string的分配比较特殊;
  • 其次,这个object对象必须是 多个线程同时能够识别或可见的,这样才能起到作用;
  • 还有,object的定义最好是private私有的,如果是public型,别的代码对其访问时,同时某个线程正在锁定,就会造成等待;
  • 最后,这个object其实是一个辅助变量,唯一的意义就是lock(object),对于object不要用作他用。

其原理很简单,就是lock住多个线程共同识别的对象,当其他线程访问某段代码段时发现这个object被锁定,就必须排队等待,直到这个object被释放,真正起到锁定代码段的关键是这个object对象,不是其他。

如果定义了多个临界区,但是这些临界区使用的是同一个【锁定实例对象】也即上述的object,那么当某线程访问一个临界区时,其他临界区也将被锁定,不能被其他线程访问。

注意

临界区内本身就是为多个线程同时访问的,因此请不要在临界区内加入UI线程的东西,如控件的使用,否则可能造成死锁。

例子:

private StringBuilder _cache = new StringBuilder();//缓存,多线程争夺访问的资源
        private object _objectLock = new object();//锁对象

        void Enqueue(string val)//入队
        {
            #region 代码段1

            lock (_objectLock)
            {
                _cache.Append(val);
            }

            #endregion
        }

        string Dequeue()//出队
        {
            #region 代码段2

            lock (_objectLock)
            {
                int idx = _cache.ToString().IndexOf('\n');
                if (idx >= 0)
                {
                    string sub = _cache.ToString().Substring(0, idx + 1);
                    _cache.Remove(0, idx + 1);
                    return sub;
                }
                return null;
            }

            #endregion
        }

以上代码有两个临界区,代码段1和代码段2,当一个线程访问代码段1时,肯定代码段1被锁定,其他线程是不允许访问代码段1的,同时其他线程也是不能访问代码段2的,因为两个代码段使用的是一个锁对象_objectLock

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值