异步多线程(六)lock锁

非线程安全

   引发线程安全的原因是,多个线程可以同时操作全局变量/共享变量/静态变量/磁盘文件/数据库的值就可能存在线程安全问题,因为多个线程操作,出现了覆盖。List集合也是非线程安全的。

 

线程安全

多线程同时运行,如果每次运行的结果和单线程运行的结果一致,那么就是线程安全的。

 

Lock

概念

   解决多线程冲突问题,Lock是语法糖,Monitor.Enter,占据一个引用,别的线程就只能等着。锁的本质就是把多线程在某些特定场合下变成单线程,来完成某些特定操作。

在日常工作中,有些是特定需要锁的,更多的时候我们可以把数据拆分,避免多线程操作同一个数据,这样既安全又高效。例如有10000个任务,那可以进行拆分,某个线程执行1-100给任务。

 

Lock锁不允许的类型

  Stringstring在内存分配上是重用的,会冲突。这么话应该这么理解,比如你定义一个变量name=张三”,再定义一个变量temeName=张三,那么在C#内存分配时会指向同一个引用。

  Null:可以运行,不能编译通过。

 

详解Lock

Lock锁的两钟方式:

Lock(this)不推荐的锁如果只是当前内部实例使用,则不会冲突。外面如果也要用实例,就冲突了。 

 

        public void DoTest() {
            //递归调用 lock(this)不会死锁,原因:这里是同一个线程,这个引用就是被这个线程锁占据
            //锁的本质是让这个引用不会被其他线程所占据
        lock (this)
        {
                Thread.Sleep(500);
                iDotestNum++;
                if (DateTime.Now.Day < 13&&iDotestNum<10)
                {
                    
                    Console.WriteLine($"这是第{DateTime.Now.Day}天,第{iDotestNum}次");
                    this.DoTest();
                }
                else {
                    Console.WriteLine("结束啦");
                }
                }
        }

        private int iDotestNum = 0;

 

 

外部也要使用实例:

            Test test = new Test();
            Task.Delay(1000).ContinueWith(t =>
            {
                lock (test)//此处是锁住test实例
                {
                    Console.WriteLine("*********Start**********");
                    Thread.Sleep(5000);
                    Console.WriteLine("*********End**********");
                }
            });
            //会冲突,因为DoTest方法里的lock(this)就是锁住当前的实例即:test
            test.DoTest();

        public class Test{ 

        public void DoTest() {
            //递归调用 lock(this)不会死锁,原因:这里是同一个线程,这个引用就是被这个线程锁占据
            //锁的本质是让这个引用不会被其他线程所占据
        lock (this)
        {
                Thread.Sleep(500);
                iDotestNum++;
                if (DateTime.Now.Day < 13&&iDotestNum<10)
                {
                    
                    Console.WriteLine($"这是第{DateTime.Now.Day}天,第{iDotestNum}次");
                    this.DoTest();
                }
                else {
                    Console.WriteLine("结束啦");
                }
                }
        }

        private int iDotestNum = 0;
    }

 

 

 

 

 

标准锁,微软推荐的标准锁

 

private static readonly object Form_Lock = new object();

lock(Form_Lock);

            #region 标准锁

            for (int i = 0; i < 1000; i++)
            {      
                   Task.Run(() =>
                   {
                       lock (Form_Lock)// 任意时刻只有一个线程能进入方法块儿
                       {
                           intAsyncNum++;
                       }
                   });
            }
            Console.WriteLine($"intAsyncNum={intAsyncNum}");

            #endregion

 

转载于:https://www.cnblogs.com/JohnTang/p/11010476.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值