当前位置:网站首页>Analysis and understanding of atomicintegerarray source code

Analysis and understanding of atomicintegerarray source code

2022-04-23 13:56:00 InfoQ

  • 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(&quot;index &quot; + 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 
    《 A big factory Java Analysis of interview questions + Back end development learning notes + The latest architecture explanation video + Practical project source code handout 》 Free open source Prestige search official account 【 Advanced programming 】
     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=&quot;package-summary.html#Spurious&quot;>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

版权声明
本文为[InfoQ]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/04/202204231353209864.html