I have lots of code which uses JAXB Marshaller and Unmarshaller class member objects (i.e. I create these in the constructor of a class and use them in several methods of the class). I've just found out that these two JAXB classes are not thread safe (see here).
I'd prefer not to create these Marshaller and Unmarshaller objects each time I need them, so I wonder if I can get around the thread safety issue by just placing the marshal/unmarshal code in a synchronized block? Something like this:
If this isn't the best way to go about it then please enlighten me as to why not and a better solution -- I'd really appreciate it, as thread programming is a weak point for me which I'd like to improve upon. Thanks in advance.
--James [ July 18, 2007: Message edited by: James Adams ]
That looks good, and is probably the first thing to try. It could give you poor performance if there are many threads accessing the same instance concurrently, and the time required for JAXB methods is significant compared to all the other things this class does. In that case, the JAXB could become a bottleneck for many threads as they all wait to use the same Marshaller. An alternate approach is to use ThreadLocal, and have a different Marshaller for each thread:
The first time a particular thread invokes marshallers.get(), the ThreadLocal sees that there's no Marshaller associated with that thread, and calls initialValue() to produce one. Subsequent calls to get() from the same thread simply return the same Marshaller produced the first time.
This approach works particularly well with a thread pool, where each Thread will stick around for a long time, and will get many opportunities to re-use its Marshaller. If instead you're using new Thread() a lot, then each thread will probably force the creation of a new Marshaller anyway, and you're not gaining much with this approach.