Java并发编程-CAS操作

CAS 指的是目前 CPU 中广泛支持的一种对内存中的共享数据进行操作的特殊指令,这个指令会对内存中的共享数据进行原子性操作。

CAS 操作过程

CPU 会将内存中将要被更改的数据与期望值做比较,相同则将内存中的值替换成新的值,否则不做操作,最后 CPU 将原来的旧值返回。其中这一系列操作是原子的。
CAS 含义:“我认为原有的值应该是什么,如果是,则将原有的值更新为新值,否则不做修改,并告诉我原来的值是多少”。

CAS 原理图

CAS原理图.png

分析:图中有三个参数

  • V 表示要更新的变量
  • E 表示期望值(旧值)
  • N 表示新值

V 变量是线程从内存中获取到的值,E 变量是自定义的值,N 变量是条件成立后会修改的值。

代码示例

首先看一个简单的示例:

if (xxx) {
  a = a + 1;
}

如果在做 a = a + 1 之前 a 的值被其它线程修改了则会发生问题。因为该操作分为三个子步骤进行,不是原子性。这时可以采用锁解决此问题,但锁机制会带来上下文切换开销,CAS 也可以解决此问题,代码如下:

int V = A;
if (A.compareAndSet(V, A + 1)) {
  xxx
} else {
  xxx
}

这样的话一旦 A 的值被修改 A + 1 就不会执行了。
但是上面代码判断一次之后就结束了,如果还想执行 A + 1 操作就需要使用 for(;😉 无限循环,代码如下:

for (;;) { 
  int V = A; 
  if (A.compareAndSet(V, A + 1)) { 
      xxx 
      return; 
  } else { 
      xxx 
  } 
}

ABA 问题

简单理解:就是生活中的掉包,小偷看上你的真皮钱包,他用一个假的钱包(外观一模一样)趁你不注意换了你的钱包,你并不会有察觉。
标准解释:ABA 问题也就是发生 a++ 之间,a 的值可能被多个线程修改,不过最后都回到了最初的值,但 CAS 会认为 a 的值并没有改变。

posted @ 2018-12-27 11:02  扇影无风  阅读(208)  评论(0编辑  收藏  举报