On Jul 13, 2009, at 7:37 PM, Tatu Saloranta wrote:
> On Mon, Jul 13, 2009 at 6:15 AM, Martin Probst<mail_at_martin-
> probst.com> wrote:
>>> Given we are close to releasing i have taken the conservative step
>>> of
>>> creating and storing factories in thread locals.
>>
>> Why do you bother with caching them anyways?
>>
>> If it's for performance reasons, I would suggest to implement the
>> simple solution (new factory on every request), then measure, and
>> then
>> maybe do something about it. As far as I can see there is nothing
>> expensive at least in DocumentBuilderFactory.
>
> Because construction of these factories is VERY inefficient. Or
> rather, not construction, but locating actual implementation using the
> convoluted logic, which essentially may go through every single
> (possibly compressed) jar file within your classpath, looking for
> WEB-INF/resources file that contains relevant setting(s).
> You can measure this to see how much it's for your specific
> environment; typical numbers are in two-digit milliseconds.
>
> As to reusability, despite all claims to contrary, I have yet to see a
> case where it would be anything but "safe-after-you-have-configured
> it".
>
> That is: what I do is that iff I can configure factory instance up
> front, instance will be thread-safe after this. What this means, then,
> is that either
>
> (a) factory must be created eagerly when app/service starts, OR
> (b) accessor must be synchronized, if lazy instantiation is needed.
>
> Creating a factory per ThreadLocal is not a good solution mostly
> because some resources (symbol tables, possibly low-level buffers) are
> retained on per-factory basis. As such, you can have 150x (or
> whatever, max number of concurrent threads ever needed) copies of
> these for app server.
>
The trouble is i do not know how the JAXP/StAX implementations of the
factories behave, so i had to take a very conservative position. I
have to say it: it completely sucks to have to do this!
Possibly one other solution is to wrap the factory and:
1) synchronize the wrapper methods to create parser instances; and
2) throw unsupported operation exceptions for methods that modify state.
but even then i do not know if, when parsing, the parser may modify
some stored state on the factory.
> But if this is done, ThreadLocals should use soft references to refer
> to factory. That allows GC to dump them if and as needed. That's an ok
> approach.
>
Hmm... so the likelihood is if a thread goes idle for a bit the
factories could be GC'ed. Then if the thread starts getting used for
multiple requests, new factory instances will be created and reused,
because the time between requests is smaller than the time to check if
those objects would be GC'ed ?
So you mean support ThreadLocal<SoftReference<T>> and if the value of
the SoftReference returns null the value in the thread local is
replaced with a new instance ?
Paul.