突击并发编程JUC系列演示代码地址:
https://github.com/mtcarpenter/JavaTutorial

上一个章节咱们学习原子更新根本类型类,如果没有印象的小伙伴能够通过底部的链接回头看下,本章节次要介绍原子更新数组类型。

数组类型

数组类型就是通过原子的形式更新数组里的某个元素,Atomic包提供了以下4个类。

AtomicLongArray 罕用办法如下

办法名阐明
long getAndIncrement(int i)以原子形式将地位i处的元素原子设置为给定值,并返回旧值。
long incrementAndGet(int i)以原子形式将索引i处以原子形式自增元素,并返回减少之后的值。
long getAndDecrement(int i)以原子形式将索引i处的元素原子并自减1,并返回旧值。
long decrementAndGet(int i)以原子形式将索引i处的元素原子并自减1,并返回减少之后的值。
long addAndGet(int i, long delta)以原子形式将输出值与数组中索引i的元素相加。
long getAndSet(int i, long newValue)将地位i处的元素原子设置为给定值,并返回旧值。
long getAndIncrement(int i)原子地将给定的值增加到索引i的元素。
long get(int i)获取地位i的以后值。
void lazySet(int i, long newValue)最终将地位i处的元素设置为给定值。
int length()返回数组的长度。
void set(int i, long newValue)将地位i处的元素设置为给定值。
boolean compareAndSet(int i,int expect,int update)如果以后值==预期值,则以原子形式将数组地位i的元素设置成update值。
boolean weakCompareAndSet(int i, int expect, long update)如果以后值==期望值,则将地位i处的元素原子设置为给定的更新值。
................
JDK 1.8 新增
long getAndUpdate(int i, LongUnaryOperator updateFunction)应用将给定函数利用给以后值和给定值的后果原子更新以后值,返回旧值
long updateAndGet(int i, LongUnaryOperator updateFunction)应用将给定函数利用给以后值和给定值的后果原子更新以后值,返回新值
........

小试牛刀

指定大小

public class AtomicExample4 {    /**     * 初始化 数组长度为 10     */    private static AtomicLongArray arr = new AtomicLongArray(5);    private static LongUnaryOperator longUnaryOperator = new LongUnaryOperator() {        @Override        public long applyAsLong(long operand) {            // 以后索引 + 10            return operand + 10;        }    };    private static LongBinaryOperator accumulatorFunction = new LongBinaryOperator() {        @Override        public long applyAsLong(long left, long right) {            return left + right;        }    };    public static void main(String[] args) {        for (int i = 0; i < arr.length(); i++) {            System.out.println("i-" + i + "=" + arr.get(i));        }        // 以原子形式给以后索引下标为(0)值加1,返回新值 (i++): 0        System.out.println("索引 0 incrementAndGet=" + arr.getAndIncrement(0));        // 以原子形式给以后索引下标为(0)值加1,,返回新值(++i)  两次减少 : 2        System.out.println("索引 0 incrementAndGet=" + arr.incrementAndGet(0));        //以原子形式给以后索引下标为(0)值缩小 1,返回旧值 (i--):2        System.out.println("索引 0 incrementAndGet=" + arr.getAndDecrement(0));        //以原子形式给以后索引下标为(0)值缩小 1,返回旧值 (--i):0        System.out.println("索引 0 incrementAndGet=" + arr.decrementAndGet(0));        // 以原子形式将输出的数值与实例中的值(AtomicLongArray(0)里的value)相加,并返回后果 : 100        System.out.println("索引 0 addAndGet=" + arr.addAndGet(0, 100));        // 获取 AtomicLongArray 的 value 100        System.out.println("索引 0 get=" + arr.get(0));        System.out.println("*********** JDK 1.8 ***********");        //应用将给定函数利用给以后值和给定值的后果原子更新以后值,返回上一个值        // 索引下标为 0 执行指定函数 后果为 100 + 10        System.out.println("索引 0 getAndUpdate=" + arr.updateAndGet(0, longUnaryOperator));        // 索引下标为 1 执行指定函数 后果为 0 + 10        System.out.println("索引 1 getAndUpdate=" + arr.updateAndGet(1, longUnaryOperator));        // 应用给定函数利用给指定下标和给定值的后果原子更新以后值,并返回后果 20        System.out.println("索引 1 accumulateAndGet=" + arr.accumulateAndGet(1, 10, accumulatorFunction));    }}

运行后果如下:

i-0=0i-1=0i-2=0i-3=0i-4=0索引 0 incrementAndGet=0索引 0 incrementAndGet=2索引 0 incrementAndGet=2索引 0 incrementAndGet=0索引 0 addAndGet=100索引 0 get=100*********** JDK 1.8 ***********索引 0 getAndUpdate=110索引 1 getAndUpdate=10索引 1 accumulateAndGet=20

通过数组

public class AtomicExample5 {    public static void main(String[] args) {        /**         * 初始化 数组         */        long arrs[] = {5, 20, 30, 40, 50};        /**         * 将初始化数组的值 赋值给 AtomicLongArray         */        AtomicLongArray arr = new AtomicLongArray(arrs);        System.out.println("arr length=" + arr.length());        for (int i = 0; i < arr.length(); i++) {            System.out.println("i-" + i + "=" + arr.get(i));        }        // 通过set 给指定元素赋值        arr.set(0, 10);        // 通过 get 获取下标为 0 的值        System.out.println("索引 0 get = " + arr.get(0));        //如果"指定索引的值" =  "预期值" 就将指定的值更新为须要"更新的值"        // 索引为 2 如果是 20 则相等,将值更新为 30        arr.compareAndSet(2, 30, 300);        System.out.println("compareAndSet 更新索引 2 的值= " + arr.get(2));        // 与 compareAndSet  不论初始值是否为预期值都可能会无奈更新该值。        arr.weakCompareAndSet(2, 300, 3000);        System.out.println("weakCompareAndSet 更新索引 2 的值= " + arr.get(2));    }}
  • 留神常识

    • compareAndSet : 指定 索引值 和给定 预期值 如果相等,则批改值为 更新值 .
    • weakCompareAndSet : 此办法跟compareAndSet相似,然而不论初始值是否为预期值都可能会无奈更新该值。

运行后果如下:

arr length=5i-0=5i-1=20i-2=30i-3=40i-4=50索引 0 get = 10compareAndSet 更新索引 2 的值= 300weakCompareAndSet 更新索引 2 的值= 3000

总结

通过原子的形式更新数组里的某个元素,Atomic包提供了4个类,  AtomicIntegerArray 、 AtomicLongArray 、 AtomicReferenceArray 、 AtomicIntegerArray ,根本实现相似,在生活中应用频率比拟少,如果看过上一个章节的小伙伴应该对此章节的案例绝对就是驾轻就熟,还不是很相熟的小伙伴,倡议尝试在电脑中运行案例,或者本人编码实现。


欢送关注公众号 山间木匠 , 我是小春哥,从事 Java 后端开发,会一点前端、通过继续输入系列技术文章与文会友,如果本文能为您提供帮忙,欢送大家关注、 点赞、分享反对,咱们下期再见!