原 CAS的介绍
版权声明:本文为博主原创文章,请尊重他人的劳动成果,转载请附上原文出处链接和本声明。
本文链接:https://www.91mszl.com/zhangwuji/article/details/1128
CAS应用
CAS有3个操作数,内存值V,旧的预期值A,要修改的更新值B。当且仅当预期值A和内存值V相同时,将内存值V修改为B,否则什么都不做。
代码如下:
package com.mszl.thread;
import java.util.concurrent.atomic.AtomicInteger;
/**
* 功能:CAS 就是比较并交换
* 备注:更多资料请访问 http://www.91mszl.com
* @author bobo teacher
*/
public class CasDemo1 {
public static void main(String[] args) {
AtomicInteger ar=new AtomicInteger(10);
boolean flag=ar.compareAndSet(10, 2000); // 第一个参数期望值,第二个参数修改值
boolean abc=ar.compareAndSet(10, 888);
System.out.println(flag + " value:" + ar.get());
System.out.println(abc + " value:" + ar.get());
}
}
执行结果:
true value:2000
false value:2000
CAS底层:
AtomicInteger ar=new AtomicInteger(10);
ar.getAndIncrement();
(1)Unsafe 是CAS的核心类,由于java方法无法直接访问底层系统,需要通过本地(native)方法来访问,Unsafe相当于一个后门,基于该类可以直接操作特定内存的数据,Unsafe类存在于sun.misc中,其内部方法操作可以像C的指针一样直接操作内存,因为java中CAS操作的执行依赖于Unsafe类的方法。
注意:Unsafe类中的所有方法都是native修饰的,也就是会所Unsafe类中的方法都直接调用操作系统底层资料执行相应任务。
(2)变量valueOffset,我们看getAndIncrement() 方法底层。
this参数为当前对象,valueOffset表示内存偏移量。1表示加1
(3)变量value用volatile修饰,保证了多线程之间的内存可见性。
unsafe类是jdk自带的,在jdk的rt.jar包中,如下图所示。
我们使用反编译rt.jar的Unsafe.class文件
简单来说就是反复的比较并交换。
CAS的缺点:
(1)循环时间很长,开销很大。Unsafe类中,我们用到了do while(),如何是多个线程,那边可能会导致循环时间长。
(2)只能保证一个共享变量的原子操作。多个共享变量操作是,循环CAS就无法保证操作的原子性,这个时候可以用加锁来保证原子性。
(3)引出ABA问题。
2019-11-25 12:02:28 阅读(1047)
名师出品,必属精品 https://www.91mszl.com
博主信息