我爱编程

JDK 源码解析 —— AtomicInteger

2018-05-26  本文已影响23人  01_小小鱼_01

java.util.concurrent.atomic包里面的类主要是用于在高并发环境下的高效程序处理,来帮助我们简化同步处理。

AtomicInteger是一个提供原子操作的Integer类,在Java语言中,++i和i++操作并不是线程安全的,在使用的时候,不可避免的会用到synchronized关键字。而AtomicInteger则通过一种线程安全的加减操作接口,使用AtomicInteger是非常的安全的.而且因为AtomicInteger由硬件提供原子操作指令实现的。在非激烈竞争的情况下,开销更小,速度更快。
使用实例:

class TestAtomicInteger {
        private AtomicInteger count = new AtomicInteger(1);

        public void increment() {
                  count.incrementAndGet();
        }

        //不需要加锁也实现线程安全。
       public int getCount() {
                return count.get();
        }
}

首先,让我们来看看AtomicInteger的源代码

// 继承了 Number, 这主要是提供方法将数值转化为 byte, double, long等基本数据类型。
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); }
    }
    // volatile 关键字修饰, 使 value 变量的改变具有可见性, 
    // 底层实现是内存栅栏,保证每次取到的是最新值。
    private volatile int value;

    public final int get() {  
        return value;  
    }  

    public final int getAndDecrement() {  
        // 可以看到 for 是一个死循环, 是采用忙等(也叫自旋)的方式
        // 不断地尝试(乐观锁)-1 操作, 直到成功才退出。 
        for (;;) {  
            int current = get();  
            int next = current - 1;  
            if (compareAndSet(current, next))  
                return current;  
        }  
    }  

    // 利用 JNI 调用底层其他语言实现的方法, 
    // 利用操作系统提供的 CAS(只要当前值和原来不一致就重新取值直到成功) 来保证原子性。
    public final boolean compareAndSet(int expect, int update) {  
        return unsafe.compareAndSwapInt(this, valueOffset, expect, update);  
    }  
}

在这里有必要提一下CAS的操作:CAS 操作包含三个操作数 —— 内存位置(V)、预期原值(A)和新值(B)。 如果内存位置的值与预期原值相匹配,那么处理器会自动将该位置值更新为新值 。否则,处理器不做任何操作。

CAS 的缺点

参考博客
1. CAS操作
2. Java中CAS详解

上一篇 下一篇

猜你喜欢

热点阅读