C# lock 关键字的一些理解
问题1:谁是锁?
lock 这个关键字,并不是“锁”,真正的“锁”是那个被lock的Object类型的“对象”,请注意,这里为“对象”加了双引号着重强调被lock的是对象类型。
问题2:这个锁有什么用?
举个例子,多数商场厕所的蹲位都是小单间型的,也就是一次只能进去一个人,商如何确保每次只能进去一个人呢?不就是一个人进去之后顺手把门锁上么?这样你在里面干啥事,外边的人也只能等待你解放完了,才能进入。以此类推,某个 object 对象被lock之后,lock这个对象的那个线程就拥有了执行lock()后面{}的完整的独立执行权,完整且独立的执行,不可分割的执行,也就是说,{}是一块临界代码段。
看下面代码
private static object objlock = new object(); lock (objlock) { //这里要做一些事情 }
根据问题1的答案进行推导,objlock才是那把锁,lock 一下,当前线程就获得了紧跟在lock后面的{}的独立使用权,在此期间,其他谁都得等着拥有objlock钥匙的线程执行完之后才能使用{}里面的代码。
更专业一点的说法是:在.Net中,每个对象都有一个与之关联的锁,对象可以得到并释放它以便在任意时间只有一个线程可以访问对象实例变量和方法。同样.Net中的每一个对象都可以提供一个允许自己进入等待状态的机制。上面提到的独立使用权,就是对象的互斥锁。(关于这个说法,求证无果,只是从博客中找到的,msdn上没找到相关说法)。
问题3.为什么只能lock引用类型?
因为只有引用类型才有互斥锁,如果强行lock值类型,c#会把值装箱成引用类型,下一次再lock,还会装箱,这两次装箱实际上是装成了两个箱子,就不是用一个内存区间了,所以锁的概念就没有意义。
问题4.避免lock public类型的对象是为什么?
还是以厕所为例子吧,私有就好比,这把锁只有你能访问到,而且最好这把锁不会因为外力而有所改变,别人访问不到,这样才能保证你进去了,别人就进不去了,如果是公有的,就好比你蹲位小单间的锁不是安装在里面而是安装在外边的,别人想不想进就不是你所能控制的了,这样也不安全。
问题5.下面代码中_dic到底能不能被其他线程操作?
private static Dictionary<int, BoKwdCueItem> _dic=new Dictionary<int, BoKwdCueItem>(); static object _obj = new object(); lock (_obj) { ///对_dic的写操作 }
个人理解上 _dic 存在被其他线程修改的可能。
private static Dictionary<int, BoKwdCueItem> _dic=new Dictionary<int, BoKwdCueItem>(); static object _obj = new object(); lock (_obj) { ///对_dic的写操作 } public void AddToDic(int data) { _dic.Add(data); }
假设A线程执行到lock(_obj)的{}的一半的时候,B线程获取的CPU的使用权,然后B线程调用了AddToDic方法,就会修改_dic的数据。
以上内容为网上搜集与个人理解,我也不保证一定对。
原文地址:https://www.cnblogs.com/feipeng8848/p/9650294.html