zoukankan      html  css  js  c++  java
  • 线程不安全与线程安全示例

    线程不安全与线程安全 示例代码:

    class Program
        {
            static void Main(string[] args)
            {
                Console.WriteLine("Incorrect counter");
    
                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: {0}",c.Count);
                Console.WriteLine("--------------------------");
    
                Console.WriteLine("Correct counter");
    
                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: {0}", c1.Count);
    
                Console.ReadKey();
            }
    
            static void TestCounter(CounterBase c)
            {
                for (int i = 0; i < 100000; i++)
                {
                    c.Increment();
                    c.Decrement();
                }
            }
    
            class Counter : CounterBase
            {
                public int Count { get; private set; }
    
                public override void Increment()
                {
                    Count++;
                }
    
                public override void Decrement()
                {
                    Count--;
                }
            }
    
            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--;
                    }
                }
            }
    
            abstract class CounterBase
            {
                public abstract void Increment();
    
                public abstract void Decrement();
            }
        }

    线程不安全与线程安全 执行结果:

    线程不安全与线程安全 工作原理:

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

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

                 为了确保不会发生以上情形,必须保证当有线程操作counter对象时,所有其他线程必须等待直到当前线程完成操作。我们可以使用lock关键字来实现这种行为。

                 如果锁定了一个对象,需要访问该对象的所有其他线程则会处于阻塞状态,并等待直到该对象解除锁定。

                 注意:这里的线程安全代码可能会导致严重的性能问题。

  • 相关阅读:
    BigPipe学习研究
    JavaSript模块规范
    WebSocket
    图片链接转成base64
    3000多台式机组装经验分享
    android textview 自动换行 整齐排版
    android 获取所有SD卡目录
    android获取系统信息
    在电脑上用chrome浏览器调试android手机里的网页代码时,无法看到本地加载的js文件
    android 根据坐标返回触摸到的View
  • 原文地址:https://www.cnblogs.com/lztkdr/p/NoThreadSafe_ThreadSafe_Demo.html
Copyright © 2011-2022 走看看