CAS 锁

锁的四种状态和升级

锁的四种状态:无锁、偏向锁、轻量级锁和重量级锁

无锁

无锁就是没有真正意义上的上锁,所有的线程还是能访问并修改同一个资源,但是通过算法控制,实现同时只有一个线程修改成功。CAS原理及应用即是无锁的实现。无锁无法全面代替有锁,但无锁在某些场合下的性能是非常高的。

比如:

CAS全称 Compare and Swap(比较与交换),是一种无锁算法。
在不使用锁的情况下(没有线程被阻塞),实现多线程的变量同步。
CAS算法主要涉及到3个操作数:
①需要进行读写操作的值 V
②判断是否更新的比较值 A
③需要替换值V写入新的值 B

在最开始将V赋值给A,再进行数据操作生成B,需要更新V之前,
比较一下A是否还与V相等,相等说明数据未变化,执行更新操作,
不相等,则更新不能完成。

CAS全称 Compare and Swap(比较与交换),是一种无锁算法。
在不使用锁的情况下(没有线程被阻塞),实现多线程的变量同步。
CAS算法主要涉及到3个操作数:
①需要进行读写操作的值 V
②判断是否更新的比较值 A
③需要替换值V写入新的值 B

在最开始将V赋值给A,再进行数据操作生成B,需要更新V之前,
比较一下A是否还与V相等,相等说明数据未变化,执行更新操作,
不相等,则更新不能完成。

偏向锁

偏向锁是指一段同步代码一直只被一个线程所访问,那么该线程会自动获取锁,降低获取锁的成本。

> 例如:家里只有一个碗,但也只有我一个人需要一个碗吃饭,所以不存在争抢,这就是偏向锁

因为在大多数情况下,锁总都是被同一个线程多次反复获得,不存在多线程竞争,所以就出现了偏向锁。目标就是在只有一个线程执行同步代码块时能够提高性能。

偏向锁只有遇到其他线程尝试竞争偏向锁时,持有偏向锁的线程才会释放锁,线程不会主动释放偏向锁。

> 例如:我家还是只有一个碗,当我朋友来我家和我一起吃饭,这时候就有两个人,只有这一个碗吃饭,偏向锁升级

偏向锁的撤销,需要等待全局安全点(在这个时间点上没有字节码正在执行),它会首先暂停拥有偏向锁的线程,判断锁对象是否处于被锁定状态。撤销偏向锁后恢复到轻量级锁(标志位为“00”)的状态。 **当进入偏向锁的时候 先进行线程id判断,如果是同一个线程,那不会进行锁的升级,如果线程的id不同那么会 进行线程的竞争,这时候会进行锁升级;**

轻量级锁

是指当锁是偏向锁的时候,被另外的线程所访问,偏向锁就会升级为轻量级锁,其他线程会通过自旋的形式尝试获取锁,不会阻塞,从而提高性能。

如果这个更新动作成功了,那么这个线程就拥有了该对象的锁,并且对象Mark Word的锁标志位设置为“00”,表示此对象处于轻量级锁定状态。

如果轻量级锁的更新操作失败了,虚拟机首先会检查对象的Mark Word是否指向当前线程的栈帧,如果是就说明当前线程已经拥有了这个对象的锁,那就可以直接进入同步块继续执行,否则说明多个线程竞争锁。

若当前只有一个等待线程,则该线程通过自旋进行等待。但是当自旋超过一定的次数,或者一个线程在持有锁,一个在自旋,又有第三个来访时,轻量级锁升级为重量级锁。

重量级锁

> 当我和女朋友都很饿的时候,我女朋友觉得我吃的太慢了,不想等我吃完,这时候就会去争抢这唯一的一个碗先吃饭,这是重量级锁状态

升级为重量级锁时,锁标志的状态值变为“10”,此时Mark Word中存储的是指向重量级锁的指针,此时等待锁的线程都会进入阻塞状态。

这里只有如果深入了解 会涉及到 用户态(轻量级问题)和内核态(重量级问题、操作系统)的问题!!!

## 总结

> 整体的锁状态升级流程是:无锁-> 偏向锁 -> 轻量级锁 -> 重量级锁

锁状态的改变是根据竞争激烈程度进行的,在几乎无竞争的条件下,会使用偏向锁,在轻度竞争的条件下,会由偏向锁升级为轻量级锁, 在重度竞争的情况下,会升级到重量级锁。

偏向锁通过对比Mark Word 解决加锁问题,避免执行CAS操作。

轻量级锁是通过CAS操作和自旋来解决加锁问题,避免线程阻塞和唤醒带来的性能影响。

重量级锁是将除拥有锁的线程之外的线程全部阻塞。

那cas是什么? cas中会遇见哪些问题 如何解决?

cas即比较并替换,是一种实现并发算法时常用到的技术

里面有三个操作数:内存值V、旧的预期值A、要修改的值B;

当预期值A和内存值V相同时,才会将内存值修改为B并返回true,否则什么都不做并返回false。

CAS存在ABA问题,解决方案是:可以对每个值添加一个版本号来判断,CAS只是一种思想

使用CAS+版本号进行解决,对一个数据如果修改了的话,那么版本号就进行+1,然后再循环比较的时候,不仅仅比较值再根据版本号就可以解决ABA问题。

如果版本号相同我们就可以加入时间戳 当版本号和时间戳都相同时 才会进行数据的改变!

最新文章

  1. java自带工具-jps、jinfo、jstack、jstat、jmap
  2. 浅析tornado web框架
  3. lightoj 1031 区间dp
  4. 【POJ2266】【树状数组+离散化】Ultra-QuickSort
  5. android 通过post方式提交数据的最简便有效的方法
  6. 《Mastering Opencv ...读书笔记系列》车牌识别(I)
  7. Linux之特殊权限(SUID/SGID/SBIT)
  8. 【JAVAWEB学习笔记】网上商城实战2:异步加载分类、Redis缓存分类和显示商品
  9. Regular expressions in lexing and parsing(翻译)
  10. Promise实现小球的运动
  11. WPF常见主界面的布局
  12. Hibernate框架笔记04HQL_QBC查询详解_抓取策略优化机制
  13. pip改源
  14. iframe 标签属性解读
  15. jenkins+git+maven 增量部署思路以及相关脚本
  16. vmware提示请卸载干净再重新安装的解决办法
  17. 【Python62--scrapy爬虫框架】
  18. Initialization of bean failed; nested exception is java.lang.NoClassDefFoundError: javax/jms/JMSContext
  19. COGS.1822.[AHOI2013]作业(莫队 树状数组/分块)
  20. uml的几种关系总结

热门文章

  1. 像计算机科学家一样思考Python(第2版)|百度网盘免费下载|Python新手入门资料
  2. xctf-pwn level3
  3. OpenLDAP on Centos7
  4. DOM练习 选择框、表格添加、变色
  5. Git 提交、删除、切换命令
  6. 各版本arm-gcc区别与安装【转】
  7. JavaScript Symbol对象
  8. UDP 绑定信息
  9. 7.1 NOI模拟赛 计数问题 dp
  10. CF R 632 div2 1333F Kate and imperfection