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.

- DML

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
problem.

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+)

Stephen


On 31 January 2010 13:35, Alan Bateman<alan.bate...@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
fields:

  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:
  http://bugs.sun.com/view_bug.do?bug_id=6379948

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).

-Alan.



Reply via email to