lock原理及使用举例(.net)

我们经常用lock加锁,实现数据操作的安全性,本篇文章将介绍lock的实现原理及几种使用方式。

一.原理

lock的作用是将多线程“单线程化”,从而实现多线程按照顺序执行。lock其实是一个语法糖,编译器会将lock转换成monitor,看一下中间代码便一目了然.
1:c#源码
lock原理及使用举例(.net)
2:编译后的中间码,编译器根据show方法生成了一个类<>__DisplayClass3_0,在该类中包含了一个b__0方法:如下图
lock原理及使用举例(.net)
3:b__0方法中的代码如下图,我们看到此处用到了Monitor进行加锁:
lock原理及使用举例(.net)

二.使用方式

1、方式一:为了体现lock的作用,我们先看下demo
lock原理及使用举例(.net)
从结果可以看出,start和end不是成对出现的,因为使用了多线程,所以输出是乱序的:
lock原理及使用举例(.net)
下一步加锁,如图所示:
lock原理及使用举例(.net)
看下加锁后的结果:start、end 成对出现, 输出变成了顺序的,原因是加锁之后,线程要按照顺序一个一个执行。
lock原理及使用举例(.net)
2、方式二:看如下代码,Main方法和ShowLockTest使用了同一个锁,那么结果是顺序还是乱序呢?
lock原理及使用举例(.net)
lock原理及使用举例(.net)
从结果可以看出,是顺序执行的,因为这两个方法用了同一个锁(TestLock):
lock原理及使用举例(.net)
将代码稍微改动一下,让Main方法使用另外一个锁(LOCK),如下所示:
lock原理及使用举例(.net)

从结果可以看出,是乱序执行的:
lock原理及使用举例(.net)
3、方式3(string):看如下代码,Main方法和ShowLockTest用了自身定义的锁,那么是乱序还是顺序执行呢?
lock原理及使用举例(.net)
lock原理及使用举例(.net)
从执行结果看,是顺序执行的,这是为什么呢,明明使用了不同的变量,为什么还顺序执行呢,这里涉及到另外一个知识点—字符串驻留池,只要字符串内容一样,那么在内存中,只保留一份,所以 这两个私有变量指向的是同一个对象,因此就用了同一个锁。
lock原理及使用举例(.net)

4、方式4(this):看如下代码,Main方法使用了lockTest加锁,ShowThis用了this加锁,那么是乱序还是顺序执行呢?
lock原理及使用举例(.net)
lock原理及使用举例(.net)
从执行结果可以看出是顺序执行的,因为lockTest和this指的是同一个对象:
lock原理及使用举例(.net)

三.总结

1、lock原理:编译器将lock转成monitor。
2、lock作用:将多线程“单线程化”,使多线程按照顺序执行。
3、只要锁定的是同一个对象,则会顺序执行,否则乱序执行。