Fetch the repository succeeded.
/*
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
/*
*
*
*
*
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
* http://creativecommons.org/publicdomain/zero/1.0/
*/
package java.util.concurrent.atomic;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.VarHandle;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.function.BinaryOperator;
import java.util.function.UnaryOperator;
/**
* An array of object references in which elements may be updated
* atomically. See the {@link VarHandle} specification for
* descriptions of the properties of atomic accesses.
* @since 1.5
* @author Doug Lea
* @param <E> The base class of elements held in this array
*/
public class AtomicReferenceArray<E> implements java.io.Serializable {
private static final long serialVersionUID = -6209656149925076980L;
private static final VarHandle AA
= MethodHandles.arrayElementVarHandle(Object[].class);
private final Object[] array; // must have exact type Object[]
/**
* Creates a new AtomicReferenceArray of the given length, with all
* elements initially null.
*
* @param length the length of the array
*/
public AtomicReferenceArray(int length) {
array = new Object[length];
}
/**
* Creates a new AtomicReferenceArray 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 AtomicReferenceArray(E[] array) {
// Visibility guaranteed by final field guarantees
this.array = Arrays.copyOf(array, array.length, Object[].class);
}
/**
* Returns the length of the array.
*
* @return the length of the array
*/
public final int length() {
return array.length;
}
/**
* Returns the current value of the element at index {@code i},
* with memory effects as specified by {@link VarHandle#getVolatile}.
*
* @param i the index
* @return the current value
*/
@SuppressWarnings("unchecked")
public final E get(int i) {
return (E)AA.getVolatile(array, i);
}
/**
* Sets the element at index {@code i} to {@code newValue},
* with memory effects as specified by {@link VarHandle#setVolatile}.
*
* @param i the index
* @param newValue the new value
*/
public final void set(int i, E newValue) {
AA.setVolatile(array, i, newValue);
}
/**
* Sets the element at index {@code i} to {@code newValue},
* with memory effects as specified by {@link VarHandle#setRelease}.
*
* @param i the index
* @param newValue the new value
* @since 1.6
*/
public final void lazySet(int i, E newValue) {
AA.setRelease(array, i, newValue);
}
/**
* Atomically sets the element at index {@code i} to {@code
* newValue} and returns the old value,
* with memory effects as specified by {@link VarHandle#getAndSet}.
*
* @param i the index
* @param newValue the new value
* @return the previous value
*/
@SuppressWarnings("unchecked")
public final E getAndSet(int i, E newValue) {
return (E)AA.getAndSet(array, i, newValue);
}
/**
* Atomically sets the element at index {@code i} to {@code newValue}
* if the element's current value {@code == expectedValue},
* with memory effects as specified by {@link VarHandle#compareAndSet}.
*
* @param i the index
* @param expectedValue the expected value
* @param newValue the new value
* @return {@code true} if successful. False return indicates that
* the actual value was not equal to the expected value.
*/
public final boolean compareAndSet(int i, E expectedValue, E newValue) {
return AA.compareAndSet(array, i, expectedValue, newValue);
}
/**
* Possibly atomically sets the element at index {@code i} to
* {@code newValue} if the element's current value {@code == expectedValue},
* with memory effects as specified by {@link VarHandle#weakCompareAndSetPlain}.
*
* @deprecated This method has plain memory effects but the method
* name implies volatile memory effects (see methods such as
* {@link #compareAndExchange} and {@link #compareAndSet}). To avoid
* confusion over plain or volatile memory effects it is recommended that
* the method {@link #weakCompareAndSetPlain} be used instead.
*
* @param i the index
* @param expectedValue the expected value
* @param newValue the new value
* @return {@code true} if successful
* @see #weakCompareAndSetPlain
*/
@Deprecated(since="9")
public final boolean weakCompareAndSet(int i, E expectedValue, E newValue) {
return AA.weakCompareAndSetPlain(array, i, expectedValue, newValue);
}
/**
* Possibly atomically sets the element at index {@code i} to
* {@code newValue} if the element's current value {@code == expectedValue},
* with memory effects as specified by {@link VarHandle#weakCompareAndSetPlain}.
*
* @param i the index
* @param expectedValue the expected value
* @param newValue the new value
* @return {@code true} if successful
* @since 9
*/
public final boolean weakCompareAndSetPlain(int i, E expectedValue, E newValue) {
return AA.weakCompareAndSetPlain(array, i, expectedValue, newValue);
}
/**
* Atomically updates (with memory effects as specified by {@link
* VarHandle#compareAndSet}) the element at index {@code i} with
* the results of applying the given function, returning the
* previous value. The function should be side-effect-free, since
* it may be re-applied when attempted updates fail due to
* contention among threads.
*
* @param i the index
* @param updateFunction a side-effect-free function
* @return the previous value
* @since 1.8
*/
public final E getAndUpdate(int i, UnaryOperator<E> updateFunction) {
E prev = get(i), next = null;
for (boolean haveNext = false;;) {
if (!haveNext)
next = updateFunction.apply(prev);
if (weakCompareAndSetVolatile(i, prev, next))
return prev;
haveNext = (prev == (prev = get(i)));
}
}
/**
* Atomically updates (with memory effects as specified by {@link
* VarHandle#compareAndSet}) the element at index {@code i} with
* the results of applying the given function, returning the
* updated value. The function should be side-effect-free, since it
* may be re-applied when attempted updates fail due to contention
* among threads.
*
* @param i the index
* @param updateFunction a side-effect-free function
* @return the updated value
* @since 1.8
*/
public final E updateAndGet(int i, UnaryOperator<E> updateFunction) {
E prev = get(i), next = null;
for (boolean haveNext = false;;) {
if (!haveNext)
next = updateFunction.apply(prev);
if (weakCompareAndSetVolatile(i, prev, next))
return next;
haveNext = (prev == (prev = get(i)));
}
}
/**
* Atomically updates (with memory effects as specified by {@link
* VarHandle#compareAndSet}) the element at index {@code i} with
* the results of applying the given function to the current and
* given values, returning the previous value. The function should
* be side-effect-free, since it may be re-applied when attempted
* updates fail due to contention among threads. The function is
* applied with the current value of the element at index {@code i}
* as its first argument, and the given update as the second
* argument.
*
* @param i the index
* @param x the update value
* @param accumulatorFunction a side-effect-free function of two arguments
* @return the previous value
* @since 1.8
*/
public final E getAndAccumulate(int i, E x,
BinaryOperator<E> accumulatorFunction) {
E prev = get(i), next = null;
for (boolean haveNext = false;;) {
if (!haveNext)
next = accumulatorFunction.apply(prev, x);
if (weakCompareAndSetVolatile(i, prev, next))
return prev;
haveNext = (prev == (prev = get(i)));
}
}
/**
* Atomically updates (with memory effects as specified by {@link
* VarHandle#compareAndSet}) the element at index {@code i} with
* the results of applying the given function to the current and
* given values, returning the updated value. The function should
* be side-effect-free, since it may be re-applied when attempted
* updates fail due to contention among threads. The function is
* applied with the current value of the element at index {@code i}
* as its first argument, and the given update as the second
* argument.
*
* @param i the index
* @param x the update value
* @param accumulatorFunction a side-effect-free function of two arguments
* @return the updated value
* @since 1.8
*/
public final E accumulateAndGet(int i, E x,
BinaryOperator<E> accumulatorFunction) {
E prev = get(i), next = null;
for (boolean haveNext = false;;) {
if (!haveNext)
next = accumulatorFunction.apply(prev, x);
if (weakCompareAndSetVolatile(i, prev, next))
return next;
haveNext = (prev == (prev = get(i)));
}
}
/**
* Returns the String representation of the current values of array.
* @return the String representation of the current values of array
*/
public String toString() {
int iMax = array.length - 1;
if (iMax == -1)
return "[]";
StringBuilder b = new StringBuilder();
b.append('[');
for (int i = 0; ; i++) {
b.append(get(i));
if (i == iMax)
return b.append(']').toString();
b.append(',').append(' ');
}
}
/**
* Reconstitutes the instance from a stream (that is, deserializes it).
* @param s the stream
* @throws ClassNotFoundException if the class of a serialized object
* could not be found
* @throws java.io.IOException if an I/O error occurs
*/
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException {
// Note: This must be changed if any additional fields are defined
Object a = s.readFields().get("array", null);
if (a == null || !a.getClass().isArray())
throw new java.io.InvalidObjectException("Not array type");
if (a.getClass() != Object[].class)
a = Arrays.copyOf((Object[])a, Array.getLength(a), Object[].class);
Field arrayField = java.security.AccessController.doPrivileged(
(java.security.PrivilegedAction<Field>) () -> {
try {
Field f = AtomicReferenceArray.class
.getDeclaredField("array");
f.setAccessible(true);
return f;
} catch (ReflectiveOperationException e) {
throw new Error(e);
}});
try {
arrayField.set(this, a);
} catch (IllegalAccessException e) {
throw new Error(e);
}
}
// jdk9
/**
* Returns the current value of the element at index {@code i},
* with memory semantics of reading as if the variable was declared
* non-{@code volatile}.
*
* @param i the index
* @return the value
* @since 9
*/
public final E getPlain(int i) {
return (E)AA.get(array, i);
}
/**
* Sets the element at index {@code i} to {@code newValue},
* with memory semantics of setting as if the variable was
* declared non-{@code volatile} and non-{@code final}.
*
* @param i the index
* @param newValue the new value
* @since 9
*/
public final void setPlain(int i, E newValue) {
AA.set(array, i, newValue);
}
/**
* Returns the current value of the element at index {@code i},
* with memory effects as specified by {@link VarHandle#getOpaque}.
*
* @param i the index
* @return the value
* @since 9
*/
public final E getOpaque(int i) {
return (E)AA.getOpaque(array, i);
}
/**
* Sets the element at index {@code i} to {@code newValue},
* with memory effects as specified by {@link VarHandle#setOpaque}.
*
* @param i the index
* @param newValue the new value
* @since 9
*/
public final void setOpaque(int i, E newValue) {
AA.setOpaque(array, i, newValue);
}
/**
* Returns the current value of the element at index {@code i},
* with memory effects as specified by {@link VarHandle#getAcquire}.
*
* @param i the index
* @return the value
* @since 9
*/
public final E getAcquire(int i) {
return (E)AA.getAcquire(array, i);
}
/**
* Sets the element at index {@code i} to {@code newValue},
* with memory effects as specified by {@link VarHandle#setRelease}.
*
* @param i the index
* @param newValue the new value
* @since 9
*/
public final void setRelease(int i, E newValue) {
AA.setRelease(array, i, newValue);
}
/**
* Atomically sets the element at index {@code i} to {@code newValue}
* if the element's current value, referred to as the <em>witness
* value</em>, {@code == expectedValue},
* with memory effects as specified by
* {@link VarHandle#compareAndExchange}.
*
* @param i the index
* @param expectedValue the expected value
* @param newValue the new value
* @return the witness value, which will be the same as the
* expected value if successful
* @since 9
*/
public final E compareAndExchange(int i, E expectedValue, E newValue) {
return (E)AA.compareAndExchange(array, i, expectedValue, newValue);
}
/**
* Atomically sets the element at index {@code i} to {@code newValue}
* if the element's current value, referred to as the <em>witness
* value</em>, {@code == expectedValue},
* with memory effects as specified by
* {@link VarHandle#compareAndExchangeAcquire}.
*
* @param i the index
* @param expectedValue the expected value
* @param newValue the new value
* @return the witness value, which will be the same as the
* expected value if successful
* @since 9
*/
public final E compareAndExchangeAcquire(int i, E expectedValue, E newValue) {
return (E)AA.compareAndExchangeAcquire(array, i, expectedValue, newValue);
}
/**
* Atomically sets the element at index {@code i} to {@code newValue}
* if the element's current value, referred to as the <em>witness
* value</em>, {@code == expectedValue},
* with memory effects as specified by
* {@link VarHandle#compareAndExchangeRelease}.
*
* @param i the index
* @param expectedValue the expected value
* @param newValue the new value
* @return the witness value, which will be the same as the
* expected value if successful
* @since 9
*/
public final E compareAndExchangeRelease(int i, E expectedValue, E newValue) {
return (E)AA.compareAndExchangeRelease(array, i, expectedValue, newValue);
}
/**
* Possibly atomically sets the element at index {@code i} to
* {@code newValue} if the element's current value {@code == expectedValue},
* with memory effects as specified by
* {@link VarHandle#weakCompareAndSet}.
*
* @param i the index
* @param expectedValue the expected value
* @param newValue the new value
* @return {@code true} if successful
* @since 9
*/
public final boolean weakCompareAndSetVolatile(int i, E expectedValue, E newValue) {
return AA.weakCompareAndSet(array, i, expectedValue, newValue);
}
/**
* Possibly atomically sets the element at index {@code i} to
* {@code newValue} if the element's current value {@code == expectedValue},
* with memory effects as specified by
* {@link VarHandle#weakCompareAndSetAcquire}.
*
* @param i the index
* @param expectedValue the expected value
* @param newValue the new value
* @return {@code true} if successful
* @since 9
*/
public final boolean weakCompareAndSetAcquire(int i, E expectedValue, E newValue) {
return AA.weakCompareAndSetAcquire(array, i, expectedValue, newValue);
}
/**
* Possibly atomically sets the element at index {@code i} to
* {@code newValue} if the element's current value {@code == expectedValue},
* with memory effects as specified by
* {@link VarHandle#weakCompareAndSetRelease}.
*
* @param i the index
* @param expectedValue the expected value
* @param newValue the new value
* @return {@code true} if successful
* @since 9
*/
public final boolean weakCompareAndSetRelease(int i, E expectedValue, E newValue) {
return AA.weakCompareAndSetRelease(array, i, expectedValue, newValue);
}
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。