后续JDK通过CPU的cmpxchg指令 , 去比较寄存器中的 A 和 内存中的值 V 。如果相等 , 就把要写入的新值 B 存入内存中 。如果不相等 , 就将内存值 V 赋值给寄存器中的值 A 。然后通过Java代码中的while循环再次调用cmpxchg指令进行重试 , 直到设置成功为止 。
CAS虽然很高效 , 但是它也存在三大问题 , 这里也简单说一下:
1. ABA问题 。CAS需要在操作值的时候检查内存值是否发生变化 , 没有发生变化才会更新内存值 。但是如果内存值原来是A , 后来变成了B , 然后又变成了A , 那么CAS进行检查时会发现值没有发生变化 , 但是实际上是有变化的 。ABA问题的解决思路就是在变量前面添加版本号 , 每次变量更新的时候都把版本号加一 , 这样变化过程就从“A-B-A”变成了“1A-2B-3A” 。
JDK从1.5开始提供了AtomicStampedReference类来解决ABA问题 , 具体操作封装在compareAndSet()中 。compareAndSet()首先检查当前引用和当前标志与预期引用和预期标志是否相等 , 如果都相等 , 则以原子方式将引用值和标志的值设置为给定的更新值 。
2. 循环时间长开销大 。CAS操作如果长时间不成功 , 会导致其一直自旋 , 给CPU带来非常大的开销 。
3. 只能保证一个共享变量的原子操作 。对一个共享变量执行操作时 , CAS能够保证原子操作 , 但是对多个共享变量操作时 , CAS是无法保证操作的原子性的 。
Java从1.5开始JDK提供了AtomicReference类来保证引用对象之间的原子性 , 可以把多个变量放在一个对象里来进行CAS操作 。
2. 自旋锁 VS 适应性自旋锁在介绍自旋锁前 , 我们需要介绍一些前提知识来帮助大家明白自旋锁的概念 。
阻塞或唤醒一个Java线程需要操作系统切换CPU状态来完成 , 这种状态转换需要耗费处理器时间 。如果同步代码块中的内容过于简单 , 状态转换消耗的时间有可能比用户代码执行的时间还要长 。
在许多场景中 , 同步资源的锁定时间很短 , 为了这一小段时间去切换线程 , 线程挂起和恢复现场的花费可能会让系统得不偿失 。如果物理机器有多个处理器 , 能够让两个或以上的线程同时并行执行 , 我们就可以让后面那个请求锁的线程不放弃CPU的执行时间 , 看看持有锁的线程是否很快就会释放锁 。
而为了让当前线程“稍等一下” , 我们需让当前线程进行自旋 , 如果在自旋完成后前面锁定同步资源的线程已经释放了锁 , 那么当前线程就可以不必阻塞而是直接获取同步资源 , 从而避免切换线程的开销 。这就是自旋锁 。
![JAVA各种锁的优劣对比分析](http://img.jiangsulong.com/220410/20095JY1-5.jpg)
文章插图
自旋锁本身是有缺点的 , 它不能代替阻塞 。自旋等待虽然避免了线程切换的开销 , 但它要占用处理器时间 。如果锁被占用的时间很短 , 自旋等待的效果就会非常好 。反之 , 如果锁被占用的时间很长 , 那么自旋的线程只会白浪费处理器资源 。所以 , 自旋等待的时间必须要有一定的限度 , 如果自旋超过了限定次数(默认是10次 , 可以使用-XX:PreBlockSpin来更改)没有成功获得锁 , 就应当挂起线程 。
自旋锁的实现原理同样也是CAS , AtomicInteger中调用unsafe进行自增操作的源码中的do-while循环就是一个自旋操作 , 如果修改数值失败则通过循环来执行自旋 , 直至修改成功 。
![JAVA各种锁的优劣对比分析](http://img.jiangsulong.com/220410/20095L3X-6.jpg)
文章插图
自旋锁在JDK1.4.2中引入 , 使用-XX:+UseSpinning来开启 。JDK 6中变为默认开启 , 并且引入了自适应的自旋锁(适应性自旋锁) 。
自适应意味着自旋的时间(次数)不再固定 , 而是由前一次在同一个锁上的自旋时间及锁的拥有者的状态来决定 。如果在同一个锁对象上 , 自旋等待刚刚成功获得过锁 , 并且持有锁的线程正在运行中 , 那么虚拟机就会认为这次自旋也是很有可能再次成功 , 进而它将允许自旋等待持续相对更长的时间 。如果对于某个锁 , 自旋很少成功获得过 , 那在以后尝试获取这个锁时将可能省略掉自旋过程 , 直接阻塞线程 , 避免浪费处理器资源 。
推荐阅读
- Java虚拟机:Jvm概念和原理详解以及GC机制的分析
- Java|聊聊写简历的那些坑,为什么你投出去的简历总是石沉大海!
- 换一个卧室门锁大概多少钱,卧室门锁芯怎么换
- java 泛型详解
- WiFi系统的无线AP与AC之间的各种问题解析
- 吴裕泰连锁茶餐厅,品味精致茶文化菜肴
- 春吃芽,各种芽的功效大不同,你知道这其中的奥秘吗?
- 茶是毒素解药 不同人群喝不同的茶
- 电子驻车很多车上都有,带你解锁它的隐藏功能,别到卖车还不知道
- 肉苁蓉锁阳泡茶的方法是什么