CAS带来的问题?

为了实现线程安全问题,我们常用的方式便是使用锁,例如synchronized、Lock,但是锁是一种比较重的资源,使用锁比较损耗性能,那么我们是否可以使用其他方案实现线程安全呢,答案就是cas

CAS

cas的意思就是比较并交换的意思,通过比较并替换,便可以实现对共享变量的线程安全操作。我们来看一下下面这个例子

public class AtomicIntegerDemo {

    private static AtomicInteger atomicInteger =  new AtomicInteger();


    public static void main(String[] args) throws InterruptedException {
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        for(int i = 0; i < 1000; i++) {
            executorService.execute(()-> atomicInteger.getAndAdd(1));
        }

        Thread.sleep(1000);

        System.out.println(atomicInteger.get());
    }


}

AtomicInteger 便是采用的cas,我们来看一下他内部的实现,

public final int getAndAdd(int delta) {
    return unsafe.getAndAddInt(this, valueOffset, delta);
}

public final int getAndAddInt(Object var1, long var2, int var4) {
    int var5;
    do {
        var5 = this.getIntVolatile(var1, var2);
    } while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));

    return var5;
}

这段代码也比较好理解,就是每次获取变量最新的值,然后,用这个值和内存中的值进行比较,当相等时,便用新的值进行替换,以此来实现无锁化线程安全,那么cas是否存在问题呢?

  • 竞争激烈时,for循环次数增加,浪费CPU性能
  • 存在ABA问题

ABA问题

第一个线程读取到的最小值问A,第二个线程将A线程了 B ,此时,另外一个线程将B改成了A,这个时候,线程A再进行数据对比交换的时候,便会人为共享变量没有变化,数据交换成功,但是,实际上数据已经发生了变化

为了解决ABA为了,我们需要在数据每次发生变化时,都产生一个唯一变量,因此,我们可以采用版本号的方式,来时解决ABA问题。

问题   CAS
发表评论
留言与评论(共有 0 条评论) “”
   
验证码:

相关文章

推荐文章