JAVA并发编程学习笔记之CAS操作

发表于:2013-11-18 09:48

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:sunmenggmail    来源:51Testing软件测试网采编

  CAS操作
  CAS是单词compare and set的缩写,意思是指在set之前先比较该值有没有变化,只有在没变的情况下才对其赋值。
  我们常常做这样的操作
  if(a==b) {
  a++;
  }
  试想一下如果在做a++之前a的值被改变了怎么办?a++还执行吗?出现该问题的原因是在多线程环境下,a的值处于一种不定的状态。采用锁可以解决此类问题,但CAS也可以解决,而且可以不加锁。
int expect = a;
if(a.compareAndSet(expect,a+1)) {
doSomeThing1();
} else {
doSomeThing2();
}
  这样如果a的值被改变了a++就不会被执行。
  按照上面的写法,a!=expect之后,a++就不会被执行,如果我们还是想执行a++操作怎么办,没关系,可以采用while循环
while(true) {
int expect = a;
if (a.compareAndSet(expect, a + 1)) {
doSomeThing1();
return;
} else {
doSomeThing2();
}
}
  采用上面的写法,在没有锁的情况下实现了a++操作,这实际上是一种非阻塞算法。
  应用
   java.util.concurrent.atomic包中几乎大部分类都采用了CAS操作,以AtomicInteger为例,看看它几个主要方法的实现:
public final int getAndSet(int newValue) {
for (;;) {
int current = get();
if (compareAndSet(current, newValue))
return current;
}
}
  getAndSet方法JDK文档中的解释是:以原子方式设置为给定值,并返回旧值。原子方式体现在何处,就体现在compareAndSet上,看看compareAndSet是如何实现的:
  public final boolean compareAndSet(int expect, int update) {
  return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
  }
  不出所料,它就是采用的Unsafe类的CAS操作完成的。
21/212>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号