提交 ec5059f2 编写于 作者: D dl

7082299: AtomicReferenceArray should ensure that array is Object[]

Reviewed-by: chegar, dholmes, alanb
上级 687fc027
...@@ -34,8 +34,10 @@ ...@@ -34,8 +34,10 @@
*/ */
package java.util.concurrent.atomic; package java.util.concurrent.atomic;
import java.lang.reflect.Array;
import java.util.Arrays;
import sun.misc.Unsafe; import sun.misc.Unsafe;
import java.util.*;
/** /**
* An array of object references in which elements may be updated * An array of object references in which elements may be updated
...@@ -49,13 +51,23 @@ import java.util.*; ...@@ -49,13 +51,23 @@ import java.util.*;
public class AtomicReferenceArray<E> implements java.io.Serializable { public class AtomicReferenceArray<E> implements java.io.Serializable {
private static final long serialVersionUID = -6209656149925076980L; private static final long serialVersionUID = -6209656149925076980L;
private static final Unsafe unsafe = Unsafe.getUnsafe(); private static final Unsafe unsafe;
private static final int base = unsafe.arrayBaseOffset(Object[].class); private static final int base;
private static final int shift; private static final int shift;
private final Object[] array; private static final long arrayFieldOffset;
private final Object[] array; // must have exact type Object[]
static { 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) if ((scale & (scale - 1)) != 0)
throw new Error("data type scale not a power of two"); throw new Error("data type scale not a power of two");
shift = 31 - Integer.numberOfLeadingZeros(scale); shift = 31 - Integer.numberOfLeadingZeros(scale);
...@@ -91,7 +103,7 @@ public class AtomicReferenceArray<E> implements java.io.Serializable { ...@@ -91,7 +103,7 @@ public class AtomicReferenceArray<E> implements java.io.Serializable {
*/ */
public AtomicReferenceArray(E[] array) { public AtomicReferenceArray(E[] array) {
// Visibility guaranteed by final field guarantees // 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 { ...@@ -150,7 +162,7 @@ public class AtomicReferenceArray<E> implements java.io.Serializable {
public final E getAndSet(int i, E newValue) { public final E getAndSet(int i, E newValue) {
long offset = checkedByteOffset(i); long offset = checkedByteOffset(i);
while (true) { while (true) {
E current = (E) getRaw(offset); E current = getRaw(offset);
if (compareAndSetRaw(offset, current, newValue)) if (compareAndSetRaw(offset, current, newValue))
return current; return current;
} }
...@@ -196,7 +208,7 @@ public class AtomicReferenceArray<E> implements java.io.Serializable { ...@@ -196,7 +208,7 @@ public class AtomicReferenceArray<E> implements java.io.Serializable {
* @return the String representation of the current values of array * @return the String representation of the current values of array
*/ */
public String toString() { public String toString() {
int iMax = array.length - 1; int iMax = array.length - 1;
if (iMax == -1) if (iMax == -1)
return "[]"; return "[]";
...@@ -210,4 +222,19 @@ public class AtomicReferenceArray<E> implements java.io.Serializable { ...@@ -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.
先完成此消息的编辑!
想要评论请 注册