zoukankan      html  css  js  c++  java
  • Java原子类--AtomicLongArray

    转载请注明出处:http://www.cnblogs.com/skywang12345/p/3514604.html

    AtomicLongArray介绍和函数列表

    在"Java多线程系列--“JUC原子类”02之 AtomicLong原子类"中介绍过,AtomicLong是作用是对长整形进行原子操作。而AtomicLongArray的作用则是对"长整形数组"进行原子操作。

    AtomicLongArray函数列表

    复制代码
    // 创建给定长度的新 AtomicLongArray。
    AtomicLongArray(int length)
    // 创建与给定数组具有相同长度的新 AtomicLongArray,并从给定数组复制其所有元素。
    AtomicLongArray(long[] array)
    
    // 以原子方式将给定值添加到索引 i 的元素。
    long addAndGet(int i, long delta)
    // 如果当前值 == 预期值,则以原子方式将该值设置为给定的更新值。
    boolean compareAndSet(int i, long expect, long update)
    // 以原子方式将索引 i 的元素减1。
    long decrementAndGet(int i)
    // 获取位置 i 的当前值。
    long get(int i)
    // 以原子方式将给定值与索引 i 的元素相加。
    long getAndAdd(int i, long delta)
    // 以原子方式将索引 i 的元素减 1。
    long getAndDecrement(int i)
    // 以原子方式将索引 i 的元素加 1。
    long getAndIncrement(int i)
    // 以原子方式将位置 i 的元素设置为给定值,并返回旧值。
    long getAndSet(int i, long newValue)
    // 以原子方式将索引 i 的元素加1。
    long incrementAndGet(int i)
    // 最终将位置 i 的元素设置为给定值。
    void lazySet(int i, long newValue)
    // 返回该数组的长度。
    int length()
    // 将位置 i 的元素设置为给定值。
    void set(int i, long newValue)
    // 返回数组当前值的字符串表示形式。
    String toString()
    // 如果当前值 == 预期值,则以原子方式将该值设置为给定的更新值。
    boolean    weakCompareAndSet(int i, long expect, long update)
    复制代码

    AtomicLongArray源码分析(基于JDK1.7.0_40)

    AtomicLongArray的完整源码

     View Code

    AtomicLongArray的代码很简单,下面仅以incrementAndGet()为例,对AtomicLong的原理进行说明。
    incrementAndGet()源码如下:

    public final long incrementAndGet(int i) {
        return addAndGet(i, 1);
    }

    说明:incrementAndGet()的作用是以原子方式将long数组的索引 i 的元素加1,并返回加1之后的值。

    addAndGet()源码如下:

    复制代码
    public long addAndGet(int i, long delta) {
        // 检查数组是否越界
        long offset = checkedByteOffset(i);
        while (true) {
            // 获取long型数组的索引 offset 的原始值
            long current = getRaw(offset);
            // 修改long型值
            long next = current + delta;
            // 通过CAS更新long型数组的索引 offset的值。
            if (compareAndSetRaw(offset, current, next))
                return next;
        }
    }
    复制代码

    说明:addAndGet()首先检查数组是否越界。如果没有越界的话,则先获取数组索引i的值;然后通过CAS函数更新i的值。

    getRaw()源码如下:

    private long getRaw(long offset) {
        return unsafe.getLongVolatile(array, offset);
    }

    说明:unsafe是通过Unsafe.getUnsafe()返回的一个Unsafe对象。通过Unsafe的CAS函数对long型数组的元素进行原子操作。如compareAndSetRaw()就是调用Unsafe的CAS函数,它的源码如下:

    private boolean compareAndSetRaw(long offset, long expect, long update) {
        return unsafe.compareAndSwapLong(array, offset, expect, update);
    }

    AtomicLongArray示例

    复制代码
     1 // LongArrayTest.java的源码
     2 import java.util.concurrent.atomic.AtomicLongArray;
     3 
     4 public class LongArrayTest {
     5     
     6     public static void main(String[] args){
     7 
     8         // 新建AtomicLongArray对象
     9         long[] arrLong = new long[] {10, 20, 30, 40, 50};
    10         AtomicLongArray ala = new AtomicLongArray(arrLong);
    11 
    12         ala.set(0, 100);
    13         for (int i=0, len=ala.length(); i<len; i++) 
    14             System.out.printf("get(%d) : %s
    ", i, ala.get(i));
    15 
    16         System.out.printf("%20s : %s
    ", "getAndDecrement(0)", ala.getAndDecrement(0));
    17         System.out.printf("%20s : %s
    ", "decrementAndGet(1)", ala.decrementAndGet(1));
    18         System.out.printf("%20s : %s
    ", "getAndIncrement(2)", ala.getAndIncrement(2));
    19         System.out.printf("%20s : %s
    ", "incrementAndGet(3)", ala.incrementAndGet(3));
    20 
    21         System.out.printf("%20s : %s
    ", "addAndGet(100)", ala.addAndGet(0, 100));
    22         System.out.printf("%20s : %s
    ", "getAndAdd(100)", ala.getAndAdd(1, 100));
    23 
    24         System.out.printf("%20s : %s
    ", "compareAndSet()", ala.compareAndSet(2, 31, 1000));
    25         System.out.printf("%20s : %s
    ", "get(2)", ala.get(2));
    26     }
    27 }
    复制代码

    运行结果

    复制代码
    get(0) : 100
    get(1) : 20
    get(2) : 30
    get(3) : 40
    get(4) : 50
      getAndDecrement(0) : 100
      decrementAndGet(1) : 19
      getAndIncrement(2) : 30
      incrementAndGet(3) : 41
          addAndGet(100) : 199
          getAndAdd(100) : 19
         compareAndSet() : true
                  get(2) : 1000
    复制代码
  • 相关阅读:
    [转]对Lucene PhraseQuery的slop的理解
    Best jQuery Plugins of 2010
    15 jQuery Plugins To Create A User Friendly Tooltip
    Lucene:基于Java的全文检索引擎简介
    9 Powerful jQuery File Upload Plugins
    Coding Best Practices Using DateTime in the .NET Framework
    Best Image Croppers ready to use for web developers
    28 jQuery Zoom Plugins Creating Stunning Image Effect
    VS2005 + VSS2005 实现团队开发、源代码管理、版本控制(转)
    禁止状态栏显示超链
  • 原文地址:https://www.cnblogs.com/kexianting/p/8554301.html
Copyright © 2011-2022 走看看