CAS、sychronized原理(锁机制)

1. CAS(Compare And Swap)

(1)CAS 的由来

默认情况下,加锁都是依赖于OS 的 mutex 这个互斥锁(内核态代码)。一旦这个锁请求失败,线程就会进入阻塞状态,放弃CPU,下一次执行的时间就不确定。因此,就想了一些办法,如何不通过OS 来实现按加锁功能。

(2)实现

1)CAS伪代码

 上述整个CAS流程,对应了一个指令。

2)CAS就是乐观锁,或说是乐观锁的一种体现。是解决问题的一种思路,也可以是一种方法。

PS:被volatile 修饰的变量,其它线程一定可见;但不被volatile修饰的变量,具体什么时候可见,不确定。并不是不被volatile修饰的变量一定不可见。

3)CAS省去了加锁解锁的过程,也保证了线程安全,相比于OS的 mutex 更加高效。

CAS没有线程阻塞。

在竞争不激烈的情况下,CAS更加高效;若竞争激烈,原子类底层是 while 的循环,CPU就会一直空转。

如:

 ===》修改成原子类操作:

 (3)基于CAS实现的自旋锁

1)伪代码的实现

 2)自旋锁,是乐观锁,也是轻量级锁。

当前这把锁没有立即拿到,但预期很快就能拿到,所以一直自旋。短暂自旋几次之后,当其它线程释放锁之后,就可以立马拿到锁。

(4)CAS 的 ABA问题

1)CAS   先比较,再交换。

当前值和与气质一样时,就认为中间没有发生过变化,但存在一个漏洞。当前值和与气质一样,可能是因为其他线程进行了修改,然后又修改了回去,这个过程,仿佛中间没有发生过变化,但真实是发生了变化。

 如:

 2)解决:通过版本号。

在比较时,不仅仅比较值,还要比较版本号,这个版本号,只能增加,不能减少。

版本号只是一个概念,可以通过时间戳等方式来实现。

PS:在大部分情况下,CAS即使存在ABA 问题,也没有bug 。但在一些特定情况下,AB就会由问题,所以就会需要进行处理。

2. sychronized 原理(是一个抽象的东西)

(1)sychronized

是一个乐观锁,也是一个悲观锁(看锁的竞争程度);

不是读写锁,是普通的互斥锁;

即是轻量级锁,又是重量级锁(看锁的竞争程度,逐渐升级);

最开始是自旋锁(自旋锁也是轻量级锁),后面逐渐升级;

非公平锁;

可重入锁。

PS:广义上只考虑到JDK8(也即JDK1.8)。

PS:sychronized 的实现是基于对象的monitor 锁,每一个对象都有一个monitor对象进行能关联,底层依赖于OS 的 Mutex锁进行实现(最终也是依赖于硬件实现的(硬件先实现了一些功能,软件在硬件的基础上再去实现一些功能))。

(2)加锁工作过程

 大部分情况下,锁不仅不存在竞争,而且锁还经常由同一个对象获得。

1)偏向锁

偏向锁是一个标志,在对象头存储当前锁偏向的线程。当一个线程访问时,会先判断这个标志释放等于当前线程,若等于当前线程,就直接获得锁;若为空,就把当前锁的对象头设置成自己。

PS:并不是一把真正的锁,局势在锁对象的对象头里,设置了偏向的线程。当线程加锁时,会先判断对象头这个偏向锁是否偏向自己,是则直接使用,不是则要求取消偏向锁再升级锁进行锁的竞争。

2)自旋锁(轻量级锁)

随着其他线程进入竞争, 偏向锁状态被消除, 进入轻量级锁状态(自适应的自旋锁)。此处的轻量级锁就是通过 CAS 来实现。

3)重量级锁

如果竞争进一步激烈, 自旋不能快速获取到锁状态, 就会膨胀为重量级锁。此处的重量级锁就是指用到内核提供的 mutex 。

(3)锁消除

把锁消除,在一些不必要加锁的地方加了锁,编译器或JVM会帮助优化,把锁消掉。

PS:StringBuffer 线程安全与锁消除没有关系,是因为StringBuffer 的方法使用了sychronized 修饰。(Java里有很多数据结构是线程安全的,原因就是因为使用了sychronized修饰。)

(4)锁粗化

若加的锁粒度太小,就把加锁的范围扩大。粗细,是指代码粒度的粗细,即加锁的代码多或少。若加锁的代码非常多,就认为这个锁粒度较粗,反之则较细。

若一段代码,我们频繁加锁,sychronized就会帮我们进行锁的粗化。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值