浅析 C# Lock

Lock的定义以及概念

    实现线程同步的第一种方式是我们经常使用的lock关键字,它将包围的语句块标记为临界区,这样一次只有一个线程进入临界区并执行代码。下面第一段的几行代码是关于lock关键字的使用方式,但更重要的是我们可以通过这个例子来看到lock关键字的本质。第二段是这个方法的IL指令集,从中可以看到lock其实也是一个语法糖,它的内部实现是采用了监视器Monitor。

    lock 关键字将语句块标记为临界区,方法是获取给定对象的互斥锁,执行语句,然后释放该锁。

模拟应用场景

    用多个线程同时操作一个方法,这里模拟存钱的场景。多用户(线程)操作存钱的操作。(代码如下:)

 测试使用Winform程序,一个按钮,一个RichTextBox

代码如下:

     private static object locker = new object();//定义对象
     public static int sum = 0; //总账户余额
     
     //存钱的业务逻辑
      private void addToSum()
            {
                lock (locker)//加锁
                {
                    while (true)
                    {
                        richTextBox1.Invoke(new Action<string>((x) =>
                        {
                            richTextBox1.AppendText("正在存钱" + x);
                            sum += 100;
                            //Thread.Sleep(TimeSpan.FromMilliseconds(2000)); //此处是占用了主线程,会导致UI卡着不动,刷新迟缓。所以卸载Invoke外层去了,不信可以用下面的if做下测试
                            richTextBox1.AppendText("当前余额为" + sum + "\r\n");
                            System.Windows.Forms.Application.DoEvents();
                        }), Thread.CurrentThread.Name);
                        // if (sum >= 1000) { break; }
                        Thread.Sleep(TimeSpan.FromMilliseconds(2000));
                    }
                }
            }

下面来操作这个账户,声明多个线程来操作这个方法。看下执行效果。

      private void button1_Click(object sender, EventArgs e)
            {
                Thread th1 = new Thread(addToSum);
                th1.Name = "th1name";//指定线程名称,方便区分
                Thread th2 = new Thread(addToSum);
                th1.Start();
                Thread.Sleep(1000);
                th2.Start();
            }

分两种情况来解析

第一种是,加锁的情况下

lock (locker)//加锁

第二种是将这段代码块注释掉,分别看下执行效果。

//lock (locker)//加锁  注释掉

执行结果如下:加锁

不加锁:

 

以上为执行结果,可以看出,加锁与不加锁的情况下,执行结果显然不同。
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值