异步编程(四)多线程的同步机制-Lock关键字
一、前言
为什么需要同步机制?临界资源要求同一时间只有一个进程访问,因此在多线程中必须对临界资源的访问做同步限制。
同步分为两种,一种是直接同步,即该资源的访问是互斥的,不能允许多个线程同时访问,如打印机资源;另外一种是间接同步,即进程的执行需要其他进程的结果,那么这两个进程间的运行就有先后顺序,可以采用传统的pv操作来实现间接同步。最典型的就是生产者-消费者问题。
lock机制主要是为了解决直接同步的问题。
二、用法
以此为例,guestNum 记录了访客数量,可能有多个访客(约定每个访客就是一个独立线程),由于线程的并发执行,可能会对guestNum的数值修改前后矛盾。比如打印机实际只有一台(临界资源)
object objectA = new object();//必须是object类型吗? public void LockOp(bool isNewGuest) { lock (objectA)//lock关键字实际进行了哪些操作? { GetPrinter(); PrintDoc(); } }
抽象一下
lock (objectA) { //code }
三、必须是object类型吗?
lock操作的原理是获取对象的互斥锁,利用此互斥锁进行临界区限制。
所以,只要保证每次进入lock方法时被lock操作的都是同一个对象(内存上就是指向同一个内存位置),就可以实现lock功能。
那么,引用类型其实都可以满足此要求,因为同一个变量名标志的引用类型会始终指向同一个位置。
值类型无法满足要求,因为lock操作会使值类型装箱,那么这一次装箱的结果和下一次装箱的结果基本上是不会指向同一个位置的,这样lock也就无效了。
四、lock关键字实际进行了哪些操作?
lock实际上是Monitor的语法糖,其工作流程如下。了解Monitor,请移步
1.此对象是否被锁?如果尚未被锁,那么我可以进入其标注的临界资源(也就是code代码段),而且由我获取其互斥锁并将其锁住;
2.此对象已经被锁,那么我无法进入其标注的临界资源,需要一直等待互斥锁被释放;