The question is a bit theoretical, what is the cost of creating JAXB context, marshaller and unmarshaller?
I've found that my code could benefit from keeping the same JAXB context and possibly the same marshaller for all marshaling operations rather than creating context and marshaller on each marshaling.
So what is the cost of creating JAXB context and marshaller/unmarshaller? Is it okay to create context+marshaller for each marshaling operation or it's better to avoid it?
Even better!! Based on the good solution from the post above, create the context just-once in the constructor, and save it instead of the class.
Replace the line:
with this one:
And the main constructor with this one:
so in the getMarshaller/getUnmarshaller you can remove this line:
This improvement makes, in my case, that processing times drops from 60~70ms to just 5~10ms
JAXB 2.2 (JSR-222) has this to say, in section "4.2 JAXBContext":
Unfortunately, the specification does not make any claims regarding thread-safety of
Unmarshaller
andMarshaller
. So it is best to assume they are not.It's a pity that this isn't specifically described in the javadoc. What I can tell is that Spring uses a global JAXBContext, shared between threads, whereas it creates a new marshaller for each marshalling operation, with a javadoc comment in the code saying that JAXB marshallers are not necessarily thread-safe.
The same is said on this page: http://jaxb.java.net/guide/Performance_and_thread_safety.html.
I would guess that creating a JAXBContext is a costly operation, because it involves scanning classes and packages for annotations. But measuring it is the best way to know.
I usually solve problems like this with a
ThreadLocal
class pattern. Given the fact that you need a different marshaller for each Class, you can combine it with asingleton
-map pattern.To save you 15 minutes, of work. Here follows my implementation of a thread-safe Factory for Jaxb Marshallers and Unmarshallers.
It allows you to access the instances as follows ...
And the code you will need is a little Jaxb class that looks as follows:
I solved this problem using shared thread safe JAXBContext and thread local un/marschallers (so theoretically, there will be as many un/marshaller instances as there are threads which accessed them) with synchronization only on un/marshaller's initialization.
Note: I'm the EclipseLink JAXB (MOXy) lead and a member of the JAXB 2 (JSR-222) expert group.
JAXBContext
is thread safe and should only be created once and reused to avoid the cost of initializing the metadata multiple times.Marshaller
andUnmarshaller
are not thread safe, but are lightweight to create and could be created per operation.