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

Dr Heinz M. Kabutz heinz at javaspecialists.eu
Tue Jan 15 08:06:54 UTC 2013

Doug Lea wrote:
> On 01/14/13 17:58, Chris Hegarty wrote:
>>> I'm not sure what we are saving here. Since new TLR is a singleton, we
>>> save ~64 bytes per classloader. Worth messing with advanced
>>> serialization mechanics? Probably not. I'll publish a revised webrev 
>>> soon.
>> serialPersistentFields is really quite simple, and will help avoid 
>> any potential issues like this in the future. I can help implement 
>> this on top of your patch if you like.
> Thanks to Alan and Aleksey for noticing this and to Chris for
> offering some serialPersistentFields incantations!
> (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 ...)
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);

     * 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 {
        // 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