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)//加锁 注释掉
执行结果如下:加锁

不加锁:

以上为执行结果,可以看出,加锁与不加锁的情况下,执行结果显然不同。
欢迎大家指正。感谢。
更多博文,请点击下方链接,共同学习,共同进步。


156

被折叠的 条评论
为什么被折叠?



