mirror of
https://github.com/openjdk/jdk.git
synced 2026-02-23 08:45:33 +00:00
7082299: AtomicReferenceArray should ensure that array is Object[]
Reviewed-by: chegar, dholmes, alanb
This commit is contained in:
parent
3c41c66fb1
commit
e088fb2b1a
@ -34,8 +34,10 @@
|
||||
*/
|
||||
|
||||
package java.util.concurrent.atomic;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.Arrays;
|
||||
import sun.misc.Unsafe;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* An array of object references in which elements may be updated
|
||||
@ -49,13 +51,23 @@ import java.util.*;
|
||||
public class AtomicReferenceArray<E> implements java.io.Serializable {
|
||||
private static final long serialVersionUID = -6209656149925076980L;
|
||||
|
||||
private static final Unsafe unsafe = Unsafe.getUnsafe();
|
||||
private static final int base = unsafe.arrayBaseOffset(Object[].class);
|
||||
private static final Unsafe unsafe;
|
||||
private static final int base;
|
||||
private static final int shift;
|
||||
private final Object[] array;
|
||||
private static final long arrayFieldOffset;
|
||||
private final Object[] array; // must have exact type Object[]
|
||||
|
||||
static {
|
||||
int scale = unsafe.arrayIndexScale(Object[].class);
|
||||
int scale;
|
||||
try {
|
||||
unsafe = Unsafe.getUnsafe();
|
||||
arrayFieldOffset = unsafe.objectFieldOffset
|
||||
(AtomicReferenceArray.class.getDeclaredField("array"));
|
||||
base = unsafe.arrayBaseOffset(Object[].class);
|
||||
scale = unsafe.arrayIndexScale(Object[].class);
|
||||
} catch (Exception e) {
|
||||
throw new Error(e);
|
||||
}
|
||||
if ((scale & (scale - 1)) != 0)
|
||||
throw new Error("data type scale not a power of two");
|
||||
shift = 31 - Integer.numberOfLeadingZeros(scale);
|
||||
@ -91,7 +103,7 @@ public class AtomicReferenceArray<E> implements java.io.Serializable {
|
||||
*/
|
||||
public AtomicReferenceArray(E[] array) {
|
||||
// Visibility guaranteed by final field guarantees
|
||||
this.array = array.clone();
|
||||
this.array = Arrays.copyOf(array, array.length, Object[].class);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -150,7 +162,7 @@ public class AtomicReferenceArray<E> implements java.io.Serializable {
|
||||
public final E getAndSet(int i, E newValue) {
|
||||
long offset = checkedByteOffset(i);
|
||||
while (true) {
|
||||
E current = (E) getRaw(offset);
|
||||
E current = getRaw(offset);
|
||||
if (compareAndSetRaw(offset, current, newValue))
|
||||
return current;
|
||||
}
|
||||
@ -196,7 +208,7 @@ public class AtomicReferenceArray<E> implements java.io.Serializable {
|
||||
* @return the String representation of the current values of array
|
||||
*/
|
||||
public String toString() {
|
||||
int iMax = array.length - 1;
|
||||
int iMax = array.length - 1;
|
||||
if (iMax == -1)
|
||||
return "[]";
|
||||
|
||||
@ -210,4 +222,19 @@ public class AtomicReferenceArray<E> implements java.io.Serializable {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reconstitutes the instance from a stream (that is, deserializes it).
|
||||
* @param s the stream
|
||||
*/
|
||||
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);
|
||||
unsafe.putObjectVolatile(this, arrayFieldOffset, a);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user