在Java并发包中有一些并发框架也使用了自旋CAS的方式实现了原子操作,比如:LinkedTransferQueue类的Xfer方法。CAS虽然很高效的解决了原子操作,但是CAS仍然存在三大问题:ABA问题、循环时间长开销大、只能保证一个共享变量的原子操作

1.ABA问题

1.1.什么是ABA问题

因为CAS需要在操作值得时候,检查值有没有发生变化,如果没有发生变化则更新,但是如果一个值原来是A、变成了B、又变成了A,那么使用CAS进行检查时会发现它的值没有发生变化,但实际上却变化了。

1.2.ABA问题解决方法

1、使用版本号

ABA问题的解决思路是使用版本号,每次变量更新的时候版本号加1,那么A->B->A就会变成1A->2B->3A

2、jdk自带原子变量

从jdk1.5开始,jdk的Atomic包里就提供了一个类AtomicStampedReference来解决ABA问题,这个类中的compareAndSet方法的作用就是首先检查当前引用是否等于预期引用,并且检查当前标志是否等于预期标志,如果全部相等,则以原子方式将该引用和该标志的值更新为指定的新值

/**
* 如果当前引用等于预期引用并且当前标志等于预期标志
* 则以原子方式将该引用和该标志的值设置为给定新值
*
* @param expectedReference 预期引用值
* @param newReference 新的引用值
* @param expectedStamp 预期标记值
* @param newStamp 新标记值
* @return {@code true} if successful
*/
public boolean compareAndSet(V expectedReference,
V newReference,
int expectedStamp,
int newStamp) {
Pair<V> current = pair;
return
#预期引用==当前引用
expectedReference == current.reference &&
#预期标志==当前标志
expectedStamp == current.stamp &&
#新引用==当前引用 并且 新标志==当前标志
((newReference == current.reference &&
newStamp == current.stamp) ||
#原子更新值
casPair(current, Pair.of(newReference, newStamp)));
}

2.循环时间长开销大

自旋CAS如果长时间不成功,会给CPU带来非常大的执行开销。如果jvm能支持处理器提供的pause指令,那么效率会有一定的提升。pause指令有两个作用:

第一,它可以延迟流水线执行指令(de-pipeline),使CPU不会消耗过多的执行资源,延迟的时间取决于具体实现的版本,在一些处理器上延迟时间是零。

第二,它可以避免在退出循环的时候因内存顺序冲突(Memory Order Violation)而引起CPU流水线被清空(CPU Pipeline Flush),从而提高CPU的执行效率。

3.只能保证一个共享变量的原子操作

当对一个共享变量执行操作时,我们可以使用循环CAS的方式来保证原子操作,但是多个共享变量操作时,循环CAS就无法保证操作的原子性,这个时候就可以用锁。还有一个方法,就是把多个共享变量合并成一个共享变量来操作。比如,有两个共享变量i=2,j=a合并一下ij=2a,然后用CAS来操作ij。从java1.5开始,JDK提供了AtomicReference类来保证引用对象之间的原子性,就可以把多个变量放在一个对象里来进行CAS操作。

最新文章

  1. C# WebServices中处理XML方式
  2. TComboBoxEx和 TComboBox
  3. Python中的高级特性
  4. artTemplate 自动化编译之tmod
  5. sublime配置文件
  6. Android重要控件———ListView
  7. 用imagemagick和tesseract-ocr破解简单验证码
  8. Qt5中使用lambda表达式
  9. linux shell awk 流程控制语句(if,for,while,do)详细介绍
  10. How-to: Do Real-Time Log Analytics with Apache Kafka, Cloudera Search, and Hue
  11. 6、jeecg 笔记之 自定义excel 模板导出(一)
  12. JS---作用域和作用域链
  13. odoo开发笔记 -- 应用服务器&amp;数据库服务器分开部署
  14. 工业以太网EtherNet/IP协议安全分析整理
  15. FFT与一些冷门问题
  16. 使用Intellij搭建Servlet开发环境
  17. ccf--20150303--节日
  18. uva1354 天平难题 【位枚举子集】||【huffman树】
  19. ReactiveX 学习笔记(5)合并数据流
  20. express+mysql+vue开发环境搭建

热门文章

  1. 怎样在 Vue 中使用 v-model 实现双向数据绑定?
  2. hype-v上centos7部署高可用kubernetes集群实践
  3. maven 常见命令 学习笔记(一)之 -pl -am -amd
  4. c#连接Java后台,处理返回的数据
  5. 【原创】大叔经验分享(62)kudu副本数量
  6. Windows 7上QTP11破解及java等插件破解方法
  7. Winfrom TextBox 添加水印文字 + 字体颜色
  8. python基础:python循环、三元运算、字典、文件操作
  9. rank 和 ROW_NUMBER 区别
  10. Java语言基础(13)