写点什么

AtomicIntegerArray 源码分析与感悟

  • 2022 年 4 月 23 日
  • 本文字数:2399 字

    阅读完需:约 8 分钟

  • Expert Group and released to the public domain, as explained at

  • http://creativecommons.org/publicdomain/zero/1.0/


*/


package java.util.concurrent.atomic;


import sun.misc.Unsafe;


import java.util.*;


/**


  • An {@code int} array in which elements may be updated atomically.

  • See the {@link java.util.concurrent.atomic} package

  • specification for description of the properties of atomic

  • variables.

  • @since 1.5

  • @author Doug Lea


*/


public class AtomicIntegerArray implements java.io.Serializable {


private static final long serialVersionUID = 2862133569453604235L;


private static final Unsafe unsafe = Unsafe.getUnsafe();


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


private static final int shift;


private final int[] array;


static {


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


if ((scale & (scale - 1)) != 0)


throw new Error("data type scale not a power of two");


shift = 31 - Integer.numberOfLeadingZeros(scale);


}


private long checkedByteOffset(int i) {


if (i < 0 || i >= array.length)


throw new IndexOutOfBoundsException("index " + i);


return byteOffset(i);


}


private static long byteOffset(int i) {


return ((long) i << shift) + base;


}


/**


  • Creates a new AtomicIntegerArray of the given length, with all

  • elements initially zero.

  • @param length the length of the array


*/


public AtomicIntegerArray(int length) {


array = new int[length];


}


/**


  • Creates a new AtomicIntegerArray with the same length as, and

  • all elements copied from, the given array.

  • @param array the array to copy elements from

  • @throws NullPointerException if array is null


*/


public AtomicIntegerArray(int[] array) {


// Visibility guaranteed by final field guarantees


this.array = array.clone();


}


/**


  • Returns the length of the array.

  • @return the length of the array


*/


public final int length() {


return array.length;


}


/**


  • Gets the current value at position {@code i}.

  • @param i the index

  • @return the current value


*/


public final int get(int i) {


return getRaw(checkedByteOffset(i));


}


private int getRaw(long offset) {


return unsafe.getIntVolatile(array, offset);


}


/**


  • Sets the element at position {@code i} to the given value.

  • @param i the index

  • @param newValue the new value


*/


public final void set(int i, int newValue) {


unsafe.putIntVolatile(array, checkedByteOffset(i), newValue);


}


/**


  • Eventually sets the element at position {@code i} to the given value.

  • @param i the index

  • @param newValue the new value

  • @since 1.6


*/


public final void lazySet(int i, int newValue) {


unsafe.putOrderedInt(array, checkedByteOffset(i), newValue);


}


/**


  • Atomically sets the element at position {@code i} to the given

  • value and returns the old value.

  • @param i the index

  • @param newValue the new value

  • @return the previous value


*/


public final int getAndSet(int i, int newValue) {


long offset = checkedByteOffset(i);


while (true) {


int current = getRaw(offset);


if (compareAndSetRaw(offset, current, newValue))


return current;


}


}


/**


  • Atomically sets the element at position {@code i} to the given

  • updated value if the current value {@code ==} the expected value.

  • @param i the index

  • @param expect the expected value

  • @param update the new value

  • @return true if successful. False return indicates that

  • the actual value was not equ 《一线大厂 Java 面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义》无偿开源 威信搜索公众号【编程进阶路】 al to the expected value.


*/


public final boolean compareAndSet(int i, int expect, int update) {


return compareAndSetRaw(checkedByteOffset(i), expect, update);


}


private boolean compareAndSetRaw(long offset, int expect, int update) {


return unsafe.compareAndSwapInt(array, offset, expect, update);


}


/**


  • Atomically sets the element at position {@code i} to the given

  • updated value if the current value {@code ==} the expected value.

  • <p>May <a href="package-summary.html#Spurious">fail spuriously</a>

  • and does not provide ordering guarantees, so is only rarely an

  • appropriate alternative to {@code compareAndSet}.

  • @param i the index

  • @param expect the expected value

  • @param update the new value

  • @return true if successful.


*/


public final boolean weakCompareAndSet(int i, int expect, int update) {


return compareAndSet(i, expect, update);


}


/**


  • Atomically increments by one the element at index {@code i}.

  • @param i the index

  • @return the previous value


*/


public final int getAndIncrement(int i) {


return getAndAdd(i, 1);


}


/**


  • Atomically decrements by one the element at index {@code i}.

  • @param i the index

  • @return the previous value


*/


public final int getAndDecrement(int i) {


return getAndAdd(i, -1);


}


/**


  • Atomically adds the given value to the element at index {@code i}.

  • @param i the index

  • @param delta the value to add

  • @return the previous value


*/


public final int getAndAdd(int i, int delta) {


long offset = checkedByteOffset(i);


while (true) {


int current = getRaw(offset);


if (compareAndSetRaw(offset, current, current + delta))


return current;


}


}


/**


  • Atomically increments by one the element at index {@code i}.

  • @param i the index

用户头像

还未添加个人签名 2022.04.13 加入

还未添加个人简介

评论

发布
暂无评论
AtomicIntegerArray源码分析与感悟_Java_爱好编程进阶_InfoQ写作社区