提交 ec5059f2 编写于 作者: D dl

7082299: AtomicReferenceArray should ensure that array is Object[]

Reviewed-by: chegar, dholmes, alanb
上级 687fc027
......@@ -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);
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册