码迷,mamicode.com
首页 > Windows程序 > 详细

使用C#中的lock关键词

时间:2018-12-20 00:06:10      阅读:274      评论:0      收藏:0      [点我收藏+]

标签:实现   vat   obj   执行   stat   condition   .com   输出   sync   

  C#中lock关键字主要是为确保当一个线程使用某些资源时,同时无法其他线程无法使用该资源。下面我们看看下面的小例子。

 static void Main(string[] args)
        {
            var c = new Counter();
            var t1 = new Thread(() => TestCounter(c));
            var t2 = new Thread(() => TestCounter(c));
            var t3 = new Thread(() => TestCounter(c));
            t1.Start();
            t2.Start();
            t3.Start();
            t1.Join();
            t2.Join();
            t3.Join();
            Console.WriteLine($"Total count:{c.Count}");
            Console.WriteLine("----------------------");

            var c1 = new CounterWithLock();
            t1 = new Thread(() => TestCounter(c1));
            t2 = new Thread(() => TestCounter(c1));
            t3 = new Thread(() => TestCounter(c1));
            t1.Start();
            t2.Start();
            t3.Start();
            t1.Join();
            t2.Join();
            t3.Join();
            Console.WriteLine($"Total count:{c1.Count}");

        }
  static void TestCounter(CounterBase c)
        {
            for (int i = 0; i < 100000; i++)
            {
                c.Increment();
                c.Decrement();
            }
        }
public abstract class CounterBase
    {
        public abstract void Increment();

        public abstract void Decrement();
    }
    public class Counter:CounterBase
    {
        public int Count { get; private set; }
        public override void Increment()
        {
            Count++;
        }
        public override void Decrement()
        {
            Count--;
        }

        
    }
    public class CounterWithLock : CounterBase
    {
        private readonly object _syncRoot = new object();
        public int Count { get; private set; }
        public override void Increment()
        {
            lock (_syncRoot)
            {
                Count++;
            }
        }
        public override void Decrement()
        {
            lock (_syncRoot)
            {
                Count--;
            }
        }
    }

  下面是输出结果,可以看到输出结果并非我们所期望的0,当然结果可能为0,但大多数情况下都不是。

技术分享图片

  在这个例子中,当主程序启动时,创建了一个Counter对象。该类定义了一个可以递增和递减的简单计数器。然后我们启动了三个线程。这三个线程共享一个counter实例,在一个周期中进行一次递增和递减。这将导致不确定的结果。如果多次运行程序,则会打印出多种不同的计数器值。

  这是因为Counter类并不是线程安全的。当多个线程同时访问Counter对象时,第一个线程得到的Counter值10并增加为11。然后第二个进程得到的值是11并增加到12.第一个线程得到的Counter值12递减为11并保存在Counter中,同时第二个线程也执行了相同的操作。结果我们进行了两次递增操作但是有效的递减只有一次,这显然不对。这种情形被称为竞争条件(race condition)。竞争条件是多线程环境中非常常见的错误原因。

  为了确保不会发生以上情形,必须保证当有线程操作counter对象时,所有其他线程必须等待知道当前线程完成操作。我们可以使用lock关键词来实现这种行为。如果锁定了一个对象,需要访问该对象的所有线程都会处于阻塞状态,并等待直到该对象解除锁定。当然这有可能导致严重的性能问题,针对这一问题,我们后面再讲。

使用C#中的lock关键词

标签:实现   vat   obj   执行   stat   condition   .com   输出   sync   

原文地址:https://www.cnblogs.com/donyblog/p/10146952.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!