RFR (S): CR 8005926: (thread) Merge ThreadLocalRandom state into java.lang.Thread

Chris Hegarty chris.hegarty at oracle.com
Tue Jan 15 13:38:45 UTC 2013


On 01/15/2013 01:25 PM, Doug Lea wrote:
>
>>> (The only way to serialize a TLR represents a strange abuse to
>>> begin with. You'd need to save the result of
>>> ThreadLocalRandom.current() in a field of a serialized object.
>>> Which would be a terrible idea ...)
>
> And so, anything sensible that we do here will have the
> (too nice?) effect of "fixing" the errors of anyone
> crazy enough to do this -- rather than deserializing into
> a non-thread-local ThreadLocalRandom, it will attach to
> the common one.
>
> Given all this, I think Heinz's suggestion below looks suitable.
> Chris, do you agree about the serialization incantations?

Yes, I am starting to come to this conclusion too (Heinz's suggestion). 
There are a few @serialField tags to be added so we continue to generate 
correct javadoc. Otherwise, I think we are good. I'll follow up on this 
and send out a complete patch for review.

If the TLR spec is ever to be updated to specify that it is not ( any 
more ) serializable (Peters suggestion), writeObect throw, we can do 
this at a later stage.

-Chris.

>
> -Doug
>
> On 01/15/13 03:06, Dr Heinz M. Kabutz wrote:
>> Right, which means we should also add a readResolve() method to return
>> ThreadLocalRandom.current().  All you need to do is add this to the
>> class and
>> the format should be compatible with Java 1.7.  This means that if
>> someone made
>> the mistake of writing ThreadLocalRandom instances, they would now
>> still be able
>> to read, but would instead get the correct instance back for their
>> thread:
>>
>>     /**
>>      * We keep the same serial persistent format as in Java 1.7.
>>      */
>>     private static final ObjectStreamField[] serialPersistentFields = {
>>             new ObjectStreamField("rnd", long.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),
>>     };
>>
>>     /**
>>      * Writes the ThreadLocalRandom object to the ObjectOutputStream
>> using the
>>      * same format as in the past.
>>      */
>>     private void writeObject(ObjectOutputStream out) throws IOException {
>>         ObjectOutputStream.PutField fields = out.putFields();
>>         fields.put("rnd", rnd);
>>         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();
>>     }
>>
>>     /**
>>      * Reads the ThreadLocalRandom object from the stream in order to
>> keep
>>      * the format compatible, but does not use any of the read data.
>>      */
>>     private void readObject(ObjectInputStream in)
>>             throws ClassNotFoundException, IOException {
>>         in.readFields();
>>         // we can ignore the values, since we will replace them in the
>>         // readResolve() method anyway
>>     }
>>
>>     /**
>>      * Once the ThreadLocalRandom object has been read from the
>> stream, we
>>      * throw it away and instead return the correct instance for our
>> thread.
>>      */
>>     private Object readResolve() {
>>         return current();
>>     }
>>
>



More information about the core-libs-dev mailing list