Java并发编程札记-(三)JUC原子类-03原子方式更新数组

今天学习AtomicIntegerArray、AtomicLongArray、AtomicReferenceArray,这几个类的共同特点是都提供数组的原子方式访问和更新功能。下面以AtomicLongArray为代表,对这些类进行介绍。

AtomicLongArray可以用原子方式更新其元素的long数组,实例提供long类型数组的原子方式访问和更新功能。

API

//构造方法摘要
AtomicLongArray(int length)
          //创建给定长度的新 AtomicLongArray。
AtomicLongArray(long[] array)
          //创建与给定数组具有相同长度的新 AtomicLongArray,并从给定数组复制其所有元素。 
//方法摘要
long    addAndGet(int i, long delta)
         //以原子方式将给定值添加到索引 i 的元素。
boolean compareAndSet(int i, long expect, long update)
         //如果当前值 == 预期值,则以原子方式将该值设置为给定的更新值。
long    decrementAndGet(int i)
         //以原子方式将索引 i 的元素减1。
long    get(int i)
         //获取位置 i 的当前值。
long    getAndAdd(int i, long delta)
         //以原子方式将给定值与索引 i 的元素相加。
long    getAndDecrement(int i)
         //以原子方式将索引 i 的元素减 1。
long    getAndIncrement(int i)
         //以原子方式将索引 i 的元素加 1。
long    getAndSet(int i, long newValue)
         //以原子方式将位置 i 的元素设置为给定值,并返回旧值。
long    incrementAndGet(int i)
         //以原子方式将索引 i 的元素加1。
void    lazySet(int i, long newValue)
         //最终将位置 i 的元素设置为给定值。
int     length()
         //返回该数组的长度。
void    set(int i, long newValue)
         //将位置 i 的元素设置为给定值。
String  toString()
         //返回数组当前值的字符串表示形式。
boolean weakCompareAndSet(int i, long expect, long update)
         //如果当前值 == 预期值,则以原子方式将该值设置为给定的更新值。
//以下是JDK1.8新增的部分
long    getAndUpdate(int i, LongUnaryOperator updateFunction)
         //将当前值以原子方式更新为updateFunction方法的结果,并返回更新前的值
long updateAndGet(int i, LongUnaryOperator updateFunction)
         //将当前值以原子方式更新为updateFunction方法的结果,并返回更新后的值
long getAndAccumulate(int i, long x, LongBinaryOperator accumulatorFunction)
         //将当前值以原子方式更新为updateFunction方法的结果(方法参数为x和当前值),并返回更新前的值
long accumulateAndGet(int i, long x, LongBinaryOperator accumulatorFunction)
         //将当前值以原子方式更新为updateFunction方法的结果(方法参数为x和当前值),并返回更新后的值

例1:long型数组的原子访问和更新

import java.util.Arrays;

public class AtomicLongArrayDemo {

    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            Thread thread = new Thread() {
                public void run() {
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    if(("[100, 100, 100, 100, 100]").equals(Arrays.toString(Counter.addOne())))
                            System.out.println("计数器值最终值为[100, 100, 100, 100, 100]");
                }
            };
            thread.start();
        }
    }
}
class Counter {
    private static long[] counter = new long[]{0, 0, 0, 0, 0};

    public static long[] addOne() {
        for(int i=0;i<counter.length;i++)
            ++counter[i];
        return counter;
    }
}

测试程序在连续运行100次将数组所有元素加一的操作后,判断计数器值是否为100, 100, 100, 100, 100],如果为100, 100, 100, 100, 100]就打印计数器值最终值为100, 100, 100, 100, 100],否则就什么都不打印。
数次运行程序后,发现大多数结果是什么都没有打印,说明此计数器在多线程环境下不可用。

import java.util.concurrent.atomic.AtomicLongArray;

public class AtomicLongArrayDemo {

    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            Thread thread = new Thread() {
                public void run() {
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    if (("[100, 100, 100, 100, 100]").equals(Counter.addOne().toString())) {
                        System.out.println("计数器值最终值为[100, 100, 100, 100, 100]");
                    }
                }
            };
            thread.start();
        }
    }
}

class Counter {
    private static AtomicLongArray counter = new AtomicLongArray(new long[] {0, 0, 0, 0, 0});

    public static AtomicLongArray addOne() {
        for(int i=0;i<counter.length();i++)
            counter.incrementAndGet(i);
        return counter;
    }
}

数次运行程序后,发现结果全部为计数器值最终值为[100, 100, 100, 100, 100]

实现原理

与AtomicLong相同,AtomicLong也是基于CAS实现的。

AtomicIntegerArray、AtomicReferenceArray与AtomicLongArray很相似,就不多做介绍了。

本文就讲到这里,想了解Java并发编程更多内容请参考:

  • Java并发编程札记-目录

END.

    原文作者:java并发
    原文地址: http://blog.csdn.net/panweiwei1994/article/details/78658702
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞