zoukankan      html  css  js  c++  java
  • 【C#】为什么有可能会被多个线程修改的对象要加线程锁

    例1、不用线程锁的情况下,两个线程对同一个变量进行加减操作

    static void Main(string[] args)
    {
        Counter counter = new Counter();
        var t1 = new Thread(() => TestCounter(counter));
        var t2 = new Thread(() => TestCounter(counter));
        t1.Start();
        t2.Start();
    
        Thread.Sleep(TimeSpan.FromSeconds(3));//睡眠3秒,保证t1、t2两个线程都运行完毕
        Console.WriteLine(counter.count);
        Console.Read();
    }

      对count变量不断地加1减1,最后count应该为0,但可以看出用两个线程来进行这个操作的时候,往往得到的结果并不是0,出现错误。

    例2、使用线程锁,两个线程对同一个变量进行加减操作

    static void Main(string[] args)
    {
        CounterWithLock counterlock = new CounterWithLock();
        var t1 = new Thread(() => TestCounter(counterlock));
        var t2 = new Thread(() => TestCounter(counterlock));
        t1.Start();
        t2.Start();  
    
        Thread.Sleep(TimeSpan.FromSeconds(3));//睡眠3秒,保证t1、t2两个线程都运行完毕
        Console.WriteLine(counterlock.count);
        Console.Read();
    }

      加上线程锁后,结果正常,因此加上线程锁才能保证不会出错。

    例1、例2所用到的类和方法

    /// <summary>
    /// 对同一个变量进行1000次加减操作
    /// </summary>
    /// <param name="c"></param>
    static void TestCounter(CounterBase c)
    {
        Console.WriteLine("TestCounter start");
        for (int i = 0; i < 1000; i++)
        {
            c.Increment();
            c.Decrement();
        }
        Console.WriteLine("TestCounter end");
    }
    abstract class CounterBase
    {
        public abstract void Increment();
        public abstract void Decrement();
    }
    
    /// <summary>
    /// 没有锁
    /// </summary>
    class Counter : CounterBase
    {
        public int count { get; private set; }
    
        public override void Increment()
        {
            count ++;
        }
    
        public override void Decrement()
        {
            count --;
        }
    }
    
    /// <summary>
    /// 加锁
    /// </summary>
    class CounterWithLock : CounterBase 
    {
        private readonly object locker = new object();
        public int count { get; private set; }
    
        public override void Increment()
        {
            lock (locker)
            {
                count++;
            }
        }
    
        public override void Decrement()
        {    
            lock (locker)
            {
                count--;
            }
        }
    }
  • 相关阅读:
    kafka 配置属性
    mybatis 启动流程源码分析(二)之 Configuration-Properties解析
    mybatis 配置文件
    mybatis 启动流程源码分析(一)
    mybatis configuration
    使用函数式编程替换if-else
    mybatis 基本使用
    第十二周学习笔记
    T-SQL的进阶:超越基本级别3:构建相关子查询——701小组
    第十周学习笔记
  • 原文地址:https://www.cnblogs.com/stgp/p/6229212.html
Copyright © 2011-2022 走看看