本随笔续接:.NET同步与异步之相关背景知识(六)

 

在上一篇随笔中已经提到、解决竞争条件的典型方式就是加锁 ,那本篇随笔就重点来说一说.NET提供的最常用的锁 lock关键字 和 Monitor。

一、lock关键字Demo

        public object thisLock = new object();
        private long index;

        public void AddIndex()
        {
            lock (this.thisLock)
            {
                this.index++;

                if (this.index > long.MaxValue / 2)
                {
                    this.index = 0;
                }
         // 和 index 无关的大量操作 } }
public long GetIndex() { return this.index; }

 

这一组demo,代码简洁,逻辑简单,一个 AddIndex 方法 保证字段 index 在 0到100之间,另外一个GetIndex方法用来获取字段index的值。

但是,这一组Demo却有不少问题,甚至可以说是错误,下面我将一一进行说明:

1、忘记同步——即读写操作都需要加锁

  GetIndex方法, 由于该方法没有加锁,所以通过该方法在任何时刻都可以访问字段index的值,也就是说会恰好在某个时间点获取到 101 这个值,这一点是和初衷相违背的。

 

2、读写撕裂

  如果说读写撕裂这个问题,这个demo可能不是很直观,但是Long类型确实存在读写撕裂。比如下面的例子:

        /// <summary>
        /// 测试原子性
        /// </summary>
        public void TestAtomicity()
        {
            long test = 0;

            long breakFlag = 0;
            int index = 0;
            Task.Run(() =>
            {
                base.PrintInfo("开始循环   写数据");
                while (true)
                {
                    test = (index % 2 == 0) ? 0x0 : 0x1234567890abcdef;

                    index++;

                    if (Interlocked.Read(ref breakFlag) > 0)
                    {
                        break;
                    }
                }

                base.PrintInfo("退出循环   写数据");
            });

            Task.Run(() =>
            {
                base.PrintInfo("开始循环   读数据");
                while (true)
                {
                    long temp = test;

                    if (temp != 0 && temp != 0x1234567890abcdef)
                    {
                        Interlocked.Increment(ref breakFlag);
                        base.PrintInfo($"读写撕裂:   { Convert.ToString(temp, 16)}");
                        break;
                    }
                }

                base.PrintInfo("退出循环   读数据");
            });
        }
测试原子性操作

相关文章:

  • 2021-10-02
  • 2021-12-09
  • 2021-07-16
  • 2022-12-23
  • 2021-05-19
  • 2021-07-06
猜你喜欢
  • 2021-10-28
  • 2022-12-23
  • 2021-09-23
  • 2022-12-23
  • 2021-10-11
  • 2021-10-26
相关资源
相似解决方案