提交 b5100569 编写于 作者: C chegar

8006409: ThreadLocalRandom should dropping padding fields from its serialized form

Reviewed-by: dl, martin, alanb, shade
上级 1548b7f0
...@@ -83,22 +83,20 @@ public class ThreadLocalRandom extends Random { ...@@ -83,22 +83,20 @@ public class ThreadLocalRandom extends Random {
* programs. * programs.
* *
* Because this class is in a different package than class Thread, * Because this class is in a different package than class Thread,
* field access methods must use Unsafe to bypass access control * field access methods use Unsafe to bypass access control rules.
* rules. The base functionality of Random methods is * The base functionality of Random methods is conveniently
* conveniently isolated in method next(bits), that just reads and * isolated in method next(bits), that just reads and writes the
* writes the Thread field rather than its own field. However, to * Thread field rather than its own field. However, to conform to
* conform to the requirements of the Random constructor, during * the requirements of the Random superclass constructor, the
* construction, the common static ThreadLocalRandom must maintain * common static ThreadLocalRandom maintains an "initialized"
* initialization and value fields, mainly for the sake of * field for the sake of rejecting user calls to setSeed while
* disabling user calls to setSeed while still allowing a call * still allowing a call from constructor. Note that
* from constructor. For serialization compatibility, these * serialization is completely unnecessary because there is only a
* fields are left with the same declarations as used in the * static singleton. But we generate a serial form containing
* previous ThreadLocal-based version of this class, that used * "rnd" and "initialized" fields to ensure compatibility across
* them differently. Note that serialization is completely * versions.
* unnecessary because there is only a static singleton. But these
* mechanics still ensure compatibility across versions.
* *
* Per-instance initialization is similar to that in the no-arg * Per-thread initialization is similar to that in the no-arg
* Random constructor, but we avoid correlation among not only * Random constructor, but we avoid correlation among not only
* initial seeds of those created in different threads, but also * initial seeds of those created in different threads, but also
* those created using class Random itself; while at the same time * those created using class Random itself; while at the same time
...@@ -132,10 +130,11 @@ public class ThreadLocalRandom extends Random { ...@@ -132,10 +130,11 @@ public class ThreadLocalRandom extends Random {
private static final ThreadLocal<Double> nextLocalGaussian = private static final ThreadLocal<Double> nextLocalGaussian =
new ThreadLocal<Double>(); new ThreadLocal<Double>();
/* /**
* Field used only during singleton initialization * Field used only during singleton initialization.
* True when constructor completes.
*/ */
boolean initialized; // true when constructor completes boolean initialized;
/** Constructor used only for static singleton */ /** Constructor used only for static singleton */
private ThreadLocalRandom() { private ThreadLocalRandom() {
...@@ -184,7 +183,8 @@ public class ThreadLocalRandom extends Random { ...@@ -184,7 +183,8 @@ public class ThreadLocalRandom extends Random {
* @throws UnsupportedOperationException always * @throws UnsupportedOperationException always
*/ */
public void setSeed(long seed) { public void setSeed(long seed) {
if (initialized) // allow call from super() constructor // only allow call from super() constructor
if (initialized)
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
...@@ -357,39 +357,29 @@ public class ThreadLocalRandom extends Random { ...@@ -357,39 +357,29 @@ public class ThreadLocalRandom extends Random {
r ^= r >>> 17; r ^= r >>> 17;
r ^= r << 5; r ^= r << 5;
} }
else if ((r = (int)UNSAFE.getLong(t, SEED)) == 0) else {
r = 1; // avoid zero localInit();
if ((r = (int)UNSAFE.getLong(t, SEED)) == 0)
r = 1; // avoid zero
}
UNSAFE.putInt(t, SECONDARY, r); UNSAFE.putInt(t, SECONDARY, r);
return r; return r;
} }
// Serialization support, maintains original persistent form. // Serialization support
private static final long serialVersionUID = -5851777807851030925L; private static final long serialVersionUID = -5851777807851030925L;
/** /**
* @serialField rnd long * @serialField rnd long
* seed for random computations
* @serialField initialized boolean * @serialField initialized boolean
* @serialField pad0 long * always true
* @serialField pad1 long
* @serialField pad2 long
* @serialField pad3 long
* @serialField pad4 long
* @serialField pad5 long
* @serialField pad6 long
* @serialField pad7 long
*/ */
private static final ObjectStreamField[] serialPersistentFields = { private static final ObjectStreamField[] serialPersistentFields = {
new ObjectStreamField("rnd", long.class), new ObjectStreamField("rnd", long.class),
new ObjectStreamField("initialized", boolean.class), new ObjectStreamField("initialized", boolean.class)
new ObjectStreamField("pad0", long.class), };
new ObjectStreamField("pad1", long.class),
new ObjectStreamField("pad2", long.class),
new ObjectStreamField("pad3", long.class),
new ObjectStreamField("pad4", long.class),
new ObjectStreamField("pad5", long.class),
new ObjectStreamField("pad6", long.class),
new ObjectStreamField("pad7", long.class) };
/** /**
* Saves the {@code ThreadLocalRandom} to a stream (that is, serializes it). * Saves the {@code ThreadLocalRandom} to a stream (that is, serializes it).
...@@ -398,16 +388,8 @@ public class ThreadLocalRandom extends Random { ...@@ -398,16 +388,8 @@ public class ThreadLocalRandom extends Random {
throws java.io.IOException { throws java.io.IOException {
java.io.ObjectOutputStream.PutField fields = out.putFields(); java.io.ObjectOutputStream.PutField fields = out.putFields();
fields.put("rnd", 0L); fields.put("rnd", UNSAFE.getLong(Thread.currentThread(), SEED));
fields.put("initialized", true); fields.put("initialized", true);
fields.put("pad0", 0L);
fields.put("pad1", 0L);
fields.put("pad2", 0L);
fields.put("pad3", 0L);
fields.put("pad4", 0L);
fields.put("pad5", 0L);
fields.put("pad6", 0L);
fields.put("pad7", 0L);
out.writeFields(); out.writeFields();
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册