关于锁
关于锁
先看一段代码:
这段代码毫无疑问,结果肯定是为0的。那么再看下面的代码:
那么当我们发现当我们创建一个线程的时候,其结果就不是我们想象的为0了,并且结果并不是一个固定的数字而是一个不一定的数字,有点随机的感觉,比如说,它有可能是这样:,亦有可能是这样:,结果的话倒不是每次都相同。其原因呢,就是我们_count变量是由两个线程来操作的。而这个count++也是可以写成_count=_count+1的。_count++其实是由三条指令来执行的,第一条就是把值从变量中取出来,第二条就是把取出来的变量+1,第三条就是把新的值赋值给_count。这样的话就有可能是说主线程执行了三步,将值减到了-1,而在这中间执行这三步的中间t1线程只执行了一步,也就是说将原来的0取出来了,第二步和第三步并没有走,当主线程将其值更改为-1的时候,t1线程再执行它的第二步和第三步,那么它(也就是t1线程)此时是认为这里的值是0的,而实际上它已经变为-1了,而当t1线程一执行的时候值就变成了1了,一下子由-1变成了1,就是这样就造成了一个并发的问题。所以值就会和我们想的结果不一样。
那么要解决并发的问题,我们就可以给会并发访问的地方锁起来,再锁起来之前是先要创建一个锁对象,注意锁对象一定要是引用类型,因为如果不是引用类型,会有一个装箱和拆箱的问题,导致加锁解锁不是同一个对象而会报异常,这个是一定要注意的。当然不一定要是object类型。锁起来后,则被锁起来的代码则只能由一个线程来访问了。当然我们会发现当上锁后运行的时候会比我们不上锁的时候长一些,这个原因呢,就是线程会有会有一个等待线程释放的一个时间,故尔会产生这样的情况。那么代码和结果将会是这样的:
以上就是解决并发加锁的一个问题。另外需要注意一下的就是lock锁的一个语法。就是lock的括号里写锁的对象,大括号里写会并发的代码。这个锁是一个语法糖。其本质是这样:
那么,今天就到这里了,定有不足之处,欢迎高人赐教。