03-锁种类

1.1 乐观锁

乐观锁是一种乐观思想,即认为读多写少,遇到并发写的可能性低
每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,采取在写时先读出,然后加锁操作(比较跟上一次的修改版本,如果一样则更新),如果失败则要重复读-比较-写的操作。
Java 中的乐观锁基本都是通过 CAS 操作实现的,CAS 是一种更新的原子操作,比较当前值跟传入值是否一样,一样则更新,否则失败。

1.2 悲观锁

悲观锁是就是悲观思想,即认为写多,遇到并发写的可能性高
每次去拿数据的时候都认为别人会修改,所以每次在读写数据的时候都会上锁,这样别人想读写这个数据就会 block 直到拿到锁。
Java中的悲观锁就是synchronized同步锁。AQS框架下的锁则是先尝试cas乐观锁去获取锁,获取不到,才会转换为悲观锁,如 RetreenLock。

1.3 自旋锁

自旋锁原理非常简单,如果持有锁的线程能在很短时间内释放锁资源,那么那些等待竞争锁的线程就不需要做内核态和用户态之间的切换进入阻塞挂起状态,它们只需要等一等(自旋),等持有锁的线程释放锁后即可立即获取锁,这样就避免用户线程和内核的切换的消耗
线程自旋是需要消耗 cup 的,说白了就是让 cup 在做无用功,如果一直获取不到锁,那线程也不能一直占用 cup 自旋做无用功,所以需要设定一个自旋等待的最大时间。
如果持有锁的线程执行的时间超过自旋等待的最大时间扔没有释放锁,就会导致其它争用锁的线程在最大等待时间内还是获取不到锁,这时争用线程会停止自旋进入阻塞状态。

1.4 可重入锁(递归锁)

广义上的可重入锁,而不是单指 JAVA 下的 ReentrantLock。可重入锁,也叫做递归锁,指的是同一线程 外层函数获得锁之后 ,内层递归函数仍然有获取该锁的代码,但不受影响
在 JAVA 环境下 ReentrantLock 和 synchronized 都是 可重入锁。
扩展:可重入锁(递归锁)

1.x 其他种类锁…

公平锁与非公平锁、读写锁、共享锁与独占锁、重量级锁(Mutex Lock)、轻量级锁、偏向锁、分段锁等等…

不做赘述,知其名,自寻其意。


03-锁种类
https://janycode.github.io/2016/04/28/02_编程语言/01_Java/01_JavaSE/05_并发和锁/03-锁种类/
作者
Jerry(姜源)
发布于
2016年4月28日
许可协议