AtomicLong、AtomicIntger源码分析

    Atomic原子包下大概可以分成三类,AtomicInteger、AtomicLong、AtomicBoolean这三个是类似的,这里只写一下AtomicLong相关源码。

    Atomic包是基于CAS实现的,CAS需要三个值,分别是要更新的值V,期望值E和新值N。当且仅当V和E相等的时候才可以使用新值对V进行替换,当发生冲突时就循环此过程知道成功为止。CAS是基于UNSAFE这个类实现的,这个类拥有直接修改内存,从硬件层面操纵数据,赋值等操作,还可以修改指针,因此是不安全的类。

    这个类本身比较简练,因此代码都放在下面了。其中最重要的地方在于原子性的加法或减法比1.7更加简练,在Unsafe类中进行循环比较。

// 获取Unsafe实例,这个实例只有顶级类加载器加载的类才可以使用
    private static final Unsafe unsafe = Unsafe.getUnsafe();
    private static final long valueOffset; //地址偏移量

    /**
     * Records whether the underlying JVM supports lockless
     * compareAndSwap for longs. While the Unsafe.compareAndSwapLong
     * method works in either case, some constructions should be
     * handled at Java level to avoid locking user-visible locks.
     */
    static final boolean VM_SUPPORTS_LONG_CAS = VMSupportsCS8();

    /**
     * Returns whether underlying JVM supports lockless CompareAndSet
     * for longs. Called only once and cached in VM_SUPPORTS_LONG_CAS.
     */
    private static native boolean VMSupportsCS8();
     //获取value这个值在地址中的偏移值。
    static {
        try {
            valueOffset = unsafe.objectFieldOffset
                (AtomicLong.class.getDeclaredField("value"));
        } catch (Exception ex) { throw new Error(ex); }
    }
    //记录原子类的当前值,使用volatile保证可见性
    private volatile long value;

    /**
     * 使用初始值作为参数初始化这个类
     *
     * @param initialValue the initial value
     */
    public AtomicLong(long initialValue) {
        value = initialValue;
    }

    /**
     * 空的构造函数
     */
    public AtomicLong() {
    }

    /**
     * 获取当前类的值
     *
     * @return the current value
     */
    public final long get() {
        return value;
    }

    /**
     *给当前类设定新的值
     *
     * @param newValue the new value
     */
    public final void set(long newValue) {
        value = newValue;
    }

    /**
     * Eventually sets to the given value.
     *
     * @param newValue the new value
     * @since 1.6
     */
    public final void lazySet(long newValue) {
        unsafe.putOrderedLong(this, valueOffset, newValue);
    }

    /**
     * 使用UNsafe操作设置新值,并返回旧的值。
     *
     * @param newValue the new value
     * @return the previous value
     */
    public final long getAndSet(long newValue) {
        return unsafe.getAndSetLong(this, valueOffset, newValue);
    }

    /**
     * 如果当前值等于预期值,那么就原子性的将新值赋给当前值。
     *
     */
    public final boolean compareAndSet(long expect, long update) {
        return unsafe.compareAndSwapLong(this, valueOffset, expect, update);
    }

    /**
     * Atomically sets the value to the given updated value
     * if the current value {@code ==} the expected value.
     *
     * <p><a href="package-summary.html#weakCompareAndSet">May fail
     * spuriously and does not provide ordering guarantees</a>, so is
     * only rarely an appropriate alternative to {@code compareAndSet}.
     *
     * @param expect the expected value
     * @param update the new value
     * @return {@code true} if successful
     */
    public final boolean weakCompareAndSet(long expect, long update) {
        return unsafe.compareAndSwapLong(this, valueOffset, expect, update);
    }

    /**
     *以原子的方式返回旧值并给值加一
     *
     * @return the previous value
     */
    public final long getAndIncrement() {
        return unsafe.getAndAddLong(this, valueOffset, 1L);
    }

    /**
     * 以原子的方式返回旧值并减一
     *
     * @return the previous value
     */
    public final long getAndDecrement() {
        return unsafe.getAndAddLong(this, valueOffset, -1L);
    }

    /**
     * 以原子的方式返回旧值并加上一个给定值.
     *
     * @param delta the value to add
     * @return the previous value
     */
    public final long getAndAdd(long delta) {
        return unsafe.getAndAddLong(this, valueOffset, delta);
    }

    /**
     * 以原子的方式加一并返回
     *
     * @return the updated value
     */
    public final long incrementAndGet() {
        return unsafe.getAndAddLong(this, valueOffset, 1L) + 1L;
    }

    /**
     *以原子的形式减一并返回
     * @return the updated value
     */
    public final long decrementAndGet() {
        return unsafe.getAndAddLong(this, valueOffset, -1L) - 1L;
    }

    /**
     * 以原子的形式减去一个给定值并返回当前值,和1.7相比,1.8 的代码更加简练。
     *
     * @param delta the value to add
     * @return the updated value
     */
    public final long addAndGet(long delta) {
        return unsafe.getAndAddLong(this, valueOffset, delta) + delta;
    }

   

    /**
     * 返回字符串
     */
    public String toString() {
        return Long.toString(get());
    }

    /**
     * Returns the value of this {@code AtomicLong} as an {@code int}
     * after a narrowing primitive conversion.
     * @jls 5.1.3 Narrowing Primitive Conversions
     */
    public int intValue() {
        return (int)get();
    }

    /**
     * Returns the value of this {@code AtomicLong} as a {@code long}.
     */
    public long longValue() {
        return get();
    }

    /**
     * Returns the value of this {@code AtomicLong} as a {@code float}
     * after a widening primitive conversion.
     * @jls 5.1.2 Widening Primitive Conversions
     */
    public float floatValue() {
        return (float)get();
    }

    /**
     * Returns the value of this {@code AtomicLong} as a {@code double}
     * after a widening primitive conversion.
     * @jls 5.1.2 Widening Primitive Conversions
     */
    public double doubleValue() {
        return (double)get();
    }

一个简单的实例。

 static class Inc implements  Runnable{
        public AtomicInteger atomicInteger;
        Inc(AtomicInteger atomicInteger){
            this.atomicInteger=atomicInteger;
        }
         @Override
             public void run(){
                  for(int i=0;i<100;i++){
                      atomicInteger.incrementAndGet();
                  }
              }

    }
        public static void main(String[] args) {
            AtomicInteger atomicInteger=new AtomicInteger(0);
            ExecutorService executorService=Executors.newFixedThreadPool(10);
            for(int i=0;i<10;i++){
                executorService.submit(new Thread(new Inc(atomicInteger)));
            }
            try{//休眠五秒执行完毕
                Thread.sleep(1000*5);
            }catch (Exception e){

            }
           System.out.println(atomicInteger.get());}//最后结果是1000




猜你喜欢

转载自blog.csdn.net/pb_yan/article/details/80487452
今日推荐