龙空技术网

数组类型原子类

落叶飞翔的蜗牛 47

前言:

现时我们对“new类数组”大致比较着重,我们都需要剖析一些“new类数组”的相关资讯。那么小编在网上汇集了一些有关“new类数组””的相关文章,希望兄弟们能喜欢,朋友们一起来学习一下吧!

介绍

使用原子的方式更新数组里的某个元素

AtomicIntegerArray:整形数组原子类AtomicLongArray:长整形数组原子类AtomicReferenceArray :引用类型数组原子类

上面三个类提供的方法几乎相同,所以我们这里以 AtomicIntegerArray 为例子来介绍。

AtomicIntegerArray 类常用方法

public final int get(int i) //获取 index=i 位置元素的值public final int getAndSet(int i, int newValue)//返回 index=i 位置的当前的值,并将其设置为新值:newValuepublic final int getAndIncrement(int i)//获取 index=i 位置元素的值,并让该位置的元素自增public final int getAndDecrement(int i) //获取 index=i 位置元素的值,并让该位置的元素自减public final int getAndAdd(int i, int delta) //获取 index=i 位置元素的值,并加上预期的值boolean compareAndSet(int i, int expect, int update) //如果输入的数值等于预期值,则以原子方式将 index=i 位置的元素值设置为输入值(update)public final void lazySet(int i, int newValue)//最终 将index=i 位置的元素设置为newValue,使用 lazySet 设置之后可能导致其他线程在之后的一小段时间内还是可以读到旧的值。
AtomicIntegerArray 常见方法使用
public class AtomicIntegerArrayTest {    public static void main(String[] args) {        // TODO Auto-generated method stub        int temvalue = 0;        int[] nums = { 1, 2, 3, 4, 5, 6 };        AtomicIntegerArray i = new AtomicIntegerArray(nums);        for (int j = 0; j < nums.length; j++) {            System.out.println(i.get(j));        }        temvalue = i.getAndSet(0, 2);        System.out.println("temvalue:" + temvalue + ";  i:" + i);        temvalue = i.getAndIncrement(0);        System.out.println("temvalue:" + temvalue + ";  i:" + i);        temvalue = i.getAndAdd(0, 5);        System.out.println("temvalue:" + temvalue + ";  i:" + i);    }}
原理

AtomicIntegerArray利用Unsafe类直接操作int[]对象的内存地址,以达到操作数组元素的目的,几个关键的变量解释如下:

int base = unsafe.arrayBaseOffset(int[].class);

Unsafe类的arraBaseOffset方法:返回指定类型数组的第一个元素地址相对于数组起始地址的偏移值。

int scale = unsafe.arrayIndexScale(int[].class);

Unsafe类的arrayIndexScale方法:返回指定类型数组的元素所占用的字节数。比如int[]数组中的每个int元素占用4个字节,就返回4。

那么,通过base + i * sacle 其实就可以知道 索引i的元素在数组中的内存起始地址。

但是,观察AtomicIntegerArray的byteOffset方法,是通过i << shift + base 的公式计算元素的起始地址的:

标签: #new类数组