美文网首页Android开发Android开发
AtomicInteger原理,CAS 机制,乐观锁,ABA问题

AtomicInteger原理,CAS 机制,乐观锁,ABA问题

作者: 喂_balabala | 来源:发表于2020-12-18 15:23 被阅读0次
示例
val atomicInteger = AtomicInteger(10)
atomicInteger.decrementAndGet()// atomicInteger-- 
  • 从静态代码块可以看到,在类初始化的时候拿到值的偏移量(获取偏移量后直接操作内存,从内存取值,不通过缓冲区)。在构造函数保存初始值,并且是volatile修饰
public class AtomicInteger extends Number implements java.io.Serializable {
    private static final long serialVersionUID = 6214790243416807050L;

    private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
    private static final long VALUE;

    static {
        try {
            VALUE = U.objectFieldOffset
                (AtomicInteger.class.getDeclaredField("value"));
        } catch (ReflectiveOperationException e) {
            throw new Error(e);
        }
    }

    private volatile int value;

    /**
     * Creates a new AtomicInteger with the given initial value.
     *
     * @param initialValue the initial value
     */
    public AtomicInteger(int initialValue) {
        value = initialValue;
    }
  • 查看decrementAndGet源码
public final int decrementAndGet() {
        return U.getAndAddInt(this, VALUE, -1) - 1;
    }
  • U是sun.misc.Unsafe类里面的,找到Unsafe里面的getAndAddInt
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;
    }
  • var1就是atomic对象,var2就是偏移量,var4就是要做的减1。var5是通过对象起始地址偏移VALUE的距离,拿到9(示例代码设置的9),是从主内存拿的。
  • compareAndSwapInt就是 CAS 机制
  • 首先计算var5 + var4的值,然后存储一份,然后再通过var1, var2在内存中拿到atomic的值,对比拿到的和var5 + var4的值是否相等,如果相等就允许var5减一(var5与var5 + var4交换)然后返回,如果不等就一直循环判断。
  • 在单线程中没有意义反而变复杂了
  • 假如有AB两个线程,A线程在执行var5 + var4的操作之后时间片段用完了,切换到B线程,B线程已经走完了所有流程,值已经被修改为9。再切换到A线程的时候接着执行通过var1, var2在内存中拿到atomic的值,对比拿到的和var5 + var4的值是否相等就会发现不相等了,因为已经被修改了,然后重新执行do循环里面的操作,重新在内存取值,取到9,然后判断是相等的,也就跳出循环了。
  • 对比拿到的和var5 + var4的值是否相等和对var5赋值是有CPU保证操作是原子性的
  • 这也是乐观锁
  • 没有通过复杂的机制来阻塞线程,并且达到目的,比加锁的代码效率提高很多
  • 但是只适合少量并发中使用,高并发中会导致CPU占用率高。
  • 这种乐观锁(无锁)机制还有一个ABA问题。假如操作的是引用类型,在AB两个线程中,一开始对象是a,在循环中间把对象换成了b,然后又换成了a,对比结果还是a,但是其实中间做了很多其他事情,在并发中可能会导致严重问题


    CAS.jpg

相关文章

  • AtomicInteger原理,CAS 机制,乐观锁,ABA问题

    示例 从静态代码块可以看到,在类初始化的时候拿到值的偏移量(获取偏移量后直接操作内存,从内存取值,不通过缓冲区)。...

  • 细谈CAS与ABA

    题目:如何实现乐观锁(CAS),如何避免ABA问题? 这个题主要考查原子操作、悲观锁、乐观锁及ABA问题。 原子操...

  • CAS无锁优化&ABA问题

    本文内容: Atomic原子类CAS(无锁优化,乐观锁)ABA问题Unsafe 对某些常见操作,加锁的情况有很多,...

  • 6、多线程

    synchronized关键字与CAS机制 synchronized:悲观锁CAS 机制:乐观锁当程序的并发量比较...

  • CAS原理-ABA问题-锁升级过程

    CAS 全称:Compare and swap或者Compare and exchange翻译:比较和交换 在多线...

  • 多线程高并发:synchronized & volatile

    锁 面试题 一、CAS AtomicInteger的incrementAndGet(), 使用的是CAS-unsa...

  • Java 并发编程—CAS 机制

    CAS 机制 什么 CAS ? 在 Java 中,锁分为两类,一种是悲观锁 Synchronized ,一种是乐观...

  • CAS机制和ABA问题

    CAS无锁机制实现线程安全原理https://www.cnblogs.com/myopensource/p/817...

  • CAS乐观锁原理

    1. 乐观锁和悲观锁 悲观锁 总是假设最坏的情况,为防止每次去拿数据别人修改,每次在拿数据的时候都会上锁,这样别人...

  • Java源码系列 -- AtomicInteger

    一、前言 AtomicInteger基于CAS(Compare and Swap,比较并修改)的操作,主要实现乐观...

网友评论

    本文标题:AtomicInteger原理,CAS 机制,乐观锁,ABA问题

    本文链接:https://www.haomeiwen.com/subject/mlzxnktx.html