欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

AtomicInteger原理分析

程序员文章站 2022-07-13 14:51:15
...

看源码

public class AtomicInteger extends Number implements java.io.Serializable {
    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的本质 int value,私有的

这里要注意使用了volatile修饰,volatile 关键字

在JDK1.7及以前使用Java代码实现的自增

public final int incrementAndGet() {
    for (;;) {
        //获取volatitle修饰的变量,最新的主存值
        int current = get();
        //理论上自增值
        int next = current + 1;
        //比对,自旋
        if (compareAndSet(current, next))
            return next;
    }
}


public final boolean compareAndSet(int expect, int update) {
    return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}

1.获取volatitle修饰的变量,最新的主存值

2.value+1作为自增值

3. compare value是否就是主存值,是,set next,return next;否,循环下一次

在JDK1.8及以后

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

直接封装unsafe方法中了,保证原子性,unsafe是JDK私有的我们不能调用

AtomicInteger的优点

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

2.适合读多写少模式

但是缺点明显

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

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

号外,ThreadPoolExecutor大量引用了CAS特性

AtomicInteger原理分析

 

 

相关标签: JUC