David M. Lloyd
david.lloyd at redhat.com
Mon Feb 1 16:10:00 UTC 2010
There is no need to deal with Unsafe for this. If you use a reflection
Field, while ugly, it *does* publish writes to a final field with volatile
semantics internally. I would argue that using a ThreadLocal in this
fashion would be far uglier.
There is another alternative. Use writeReplace to write a minimal
representation class, then use readResolve on that representation object to
transform it back again using standard constructors.
On 01/31/2010 02:50 PM, Stephen Colebourne wrote:
> Thanks for the info. Unfortunately, JSR-310 cannot use unsafe, as it
> needs to be usable outside the JDK.
> For info, I compared the sizes of a neatly trimmed output (using a
> Serialization proxy class) with the best achievable without one. 277
> bytes without, 99 bytes with a proxy. So, this isn't an esoteric
> What would you think of using a ThreadLocal to cache the result value
> between readObject() and readResolve() ? (making everything transient
> and using a dedicated format)
> What do you think of the general idea of readObjectAndResolve() ? (for JDK 7+)
> On 31 January 2010 13:35, Alan Bateman<Alan.Bateman at sun.com> wrote:
>> Stephen Colebourne wrote:
>>> I thought I'd raise an issue with serialization that I've had a problem
>>> with more than once. Perhaps there is an obvious easy solution, but I can't
>>> see it (I can see hard workarounds...)
>>> In JSR-310 we have lots of immutable classes. One of these stores four
>>> private final String name
>>> private final Duration duration
>>> private final List<PeriodField> periods
>>> private final int hashCode
>>> For serialization, I only need to store the name, duration and element
>>> zero from the periods list. (The rest of the period list is a cache derived
>>> from the first element. Similarly, I want to cache the hash code in the
>>> constructor as this could be performance critical.). Storing just these
>>> fields can be done easily using writeObject()
>> In the JDK there are places that use unsafe's putObjectVolatile to
>> workaround this. It's also possible to use reflection hacks in some cases.
>> There is more discussion here:
>> Doug Lea and the concurrency group were working on a Fences API that
>> included a method for safe publication so that one can get the same effects
>> as final for cases where it's not possible to declare a field as field.
>> For the hashCode case above then perhaps it doesn't necessary to compute the
>> hash code in the constructor or when reconstituting the object. Instead
>> perhaps the hashCode method could compute and set the hashCode field when it
>> sees the value is 0 (no need to be volatile and shouldn't matter if more
>> than one thread computes it).
More information about the core-libs-dev