AtomicInteger原理

本文深入解析Java中的AtomicInteger类,探讨其如何通过CAS技术实现线程安全的整型原子操作,适用于读多写少场景,避免自旋带来的CPU性能消耗。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言:

在Java语言中,++i和i++操作并不是线程安全的,在使用的时候,不可避免的会用到synchronized关键字。而AtomicInteger则通过一种线程安全的方式进行加减操作。AtomicInteger是对int类型的一个封装,提供原子性的访问和更新操作,其原子性操作的实现是基于CAS(compare-and -swap)技术。本篇文章主要从源码上去分析下AtomicInteger实现原理。

 

源码分析:

类注释:

An int value that may be updated atomically.  See the java.util.concurrent.atomic package 

specification for description of the properties of atomic variables. An AtomicInteger is 

used in applications such as atomically  incremented counters, and cannot be used as a 

replacement for an java.lang.Integer. However, this class does extend Number to allow 

uniform access by tools and utilities that deal with numerically-based classes.

AtomicInteger是一个可以原子更新的整形数值。 AtomicInteger用于原子递增的计数器等应用程序,不能用作java.lang.Integer的替代。

 

成员变量:

    private static final long serialVersionUID = 6214790243416807050L;

    // setup to use Unsafe.compareAndSwapInt for updates
    private static final Unsafe unsafe = Unsafe.getUnsafe();
    private static final long valueOffset;

    static {
        try {
            valueOffset = unsafe.objectFieldOffset
                (AtomicInteger.class.getDeclaredField("value"));
        } catch (Exception ex) { throw new Error(ex); }
    }

    private volatile int value;

AtomicInteger使用了Unsafe类来执行CAS操作。Unsafe是java提供的获得对对象内存地址访问的类,它的作用就是在更新操作时提供“比较并替换”(CAP)的作用。valueOffset是用来记录value本身在内存的编译地址的,这个记录,也主要是为了在更新操作在内存中找到value的位置,方便比较。value使用了volatile关键字,volatile在这里可以做到的作用是使得多个线程可以共享变量。即,保证在更新操作时,当前线程可以拿到value最新的值。

 

incrementAndGet、decrementAndGet方法:

    /**
     * Atomically increments by one the current value.
     *
     * @return the updated value
     */
    public final int incrementAndGet() {
        return unsafe.getAndAddInt(this, valueOffset, 1) + 1;
    }

    /**
     * Atomically decrements by one the current value.
     *
     * @return the updated value
     */
    public final int decrementAndGet() {
        return unsafe.getAndAddInt(this, valueOffset, -1) - 1;
    }

可以看到具体实现是调用了unsafe里的方法

    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;
    }

Unsafe调用了自身的compareAndSwapInt来执行cas操作。

 

优缺点

优点:

1.乐观锁,性能较强,利用CPU自身的特性保证原子性,即CPU的指令集封装compare and swap两个操作为一个指令来保证原子性。

2.适合读多写少模式

缺点:

1.自旋,消耗CPU性能,所以写的操作较多推荐sync

2.仅适合简单的运算,否则会产生ABA问题,自旋的时候,别的线程可能更改value,然后又改回来,此时需要加版本号解决,JDK提供了AtomicStampedReference和AtomicMarkableReference解决ABA问题,提供基本数据类型和引用数据类型版本号支持
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值