|
|
51CTO旗下网站
|
|
移动端

1.7.4 CAS操作

《Java多线程与Socket:实战微服务框架》第1章多线程基础,本书尽量采用简要和通俗易懂的方式来介绍多线程知识。本节为大家介绍CAS操作。

作者:庞永华来源:电子工业出版社|2019-03-26 15:57

【大咖·来了 第7期】10月24日晚8点观看《智能导购对话机器人实践》

1.7.4 CAS操作

synchronized是一种独占锁、悲观锁,存在以下问题:

(1)某一个线程持有锁后,其他所有竞争此锁的线程都将被阻塞,影响性能。

(2)容易存在死锁的风险。

(3)锁的竞争、加锁、解锁都会导致比较多的上下文切换和调度时延,开销较大。

(4)一个优先级高的线程等待一个优先级低的线程释放锁会导致优先级倒置,引起性能风险。

volatile虽然能解决内存可见性问题,但它不能保证原子性,适用场景有限。另一个可选方案就是CAS(Compare And Swap)操作。其原理与我们常用的数据库乐观锁的实现原理相类似:

在更新某个变量前,检查变量的当前值是否符合期望值。如果相符就用新值替换当前值;否则循环重试(自旋),直到成功。

我们来看一个典型的CAS操作,即AtomicInteger类的getAndIncrement()方法:

  1. public final int getAndIncrement() {  
  2. for (;;) {  
  3. int current = get();  
  4. int next = current + 1;  
  5. if (compareAndSet(current, next))  
  6. return current;  
  7. }  
  8. }  
  9. public final boolean compareAndSet(int expect, int update) {  
  10. return unsafe.compareAndSwapInt(this, valueOffset, expect, update);  

主流CPU直接在指令层面上支持CAS指令。Java可以通过JNI(Java Native Interface)来调用这些指令,因此其执行效率很高。比如,上面代码中所调用的compareAndSwapInt()方法,就是一个这样的native方法。

CAS与volatile的结合运用是java.util.concurrent包实现非阻塞算法的基础。但是CAS操作仍然存在以下三方面的问题需要注意:

(1)ABA问题。因为CAS需要在操作值的时候检查一下值有没有发生变化,如果没有发生变化则更新,如果一个值原来是A,接着变成了B,之后又变成了A,那么使用CAS进行检查时会发现它的值没有发生变化,而不执行更新。ABA问题的解决思路就是使用版本号。java.util.concurrent.atomic.AtomicStampedReference类被设计来解决ABA问题。其compareAndSet()方法不仅会检查当前值是否等于预期,还会检查当前的版本标志是否也与预期版本标志相同。

(2)循环开销。当冲突严重时CAS中的循环重试(自旋)将增加CPU的负担。

(3)只能保证一个共享变量的原子操作。CAS不支持对多个共享变量的原子操作,这种情况仍需要锁机制来解决。也可以将多个变量组合为一个变量,或者作为成员变量放到对象中,再给这个对象加上版本号。Java 5提供了AtomicReference类来提供针对对象引用的原子性,我们可以把多个变量放在这样的一个对象里来进行操作,从而保证对这些变量操作的原子性。


喜欢的朋友可以加入官方的读书群

51CTO读书频道二维码


51CTO读书会第9群:808517103

【责任编辑:book TEL:(010)68476606】

回书目   上一节   下一节
点赞 0
分享:
大家都在看
猜你喜欢

订阅专栏+更多

Jenkins Pipeline可持续化集成

Jenkins Pipeline可持续化集成

优化运维流水线
共3章 | youerning

198人订阅学习

笑熬浆糊之职场那些事

笑熬浆糊之职场那些事

IT人的职场心法
共22章 | Bear_Boss

79人订阅学习

Redis运维秘籍

Redis运维秘籍

运维标配技术
共15章 | one叶孤舟

199人订阅学习

读 书 +更多

XML案例解析教程

本书对开发XML应用程序给予了详细指导,其中一些应用程序甚至对于您来说是完全陌生的。这些应用程序包括XML 1.0,以及与XSLT、XQuery和XPat...

订阅51CTO邮刊

点击这里查看样刊

订阅51CTO邮刊

51CTO服务号

51CTO播客