La pregunta es un poco teórica, ¿cuál es el costo de crear un contexto JAXB, marshaller y unmarshaller?
Descubrí que mi código podría beneficiarse de mantener el mismo contexto JAXB y posiblemente el mismo marshaller para todas las operaciones de clasificación en lugar de crear contexto y marshaller en cada clasificación.
Entonces, ¿cuál es el costo de crear contexto JAXB y marshaller / unmarshaller? ¿Está bien crear context + marshaller para cada operación de ordenación o es mejor evitarlo?
fuente
Idealmente, debería tener un singleton
JAXBContext
e instancias locales deMarshaller
yUnmarshaller
.JAXBContext
instancias son thread-safe mientrasMarshaller
yUnmarshaller
casos son no thread-safe y nunca deben ser compartidos a través de las roscas.fuente
Es una pena que esto no se describa específicamente en el javadoc. Lo que puedo decir es que Spring usa un JAXBContext global, compartido entre subprocesos, mientras que crea un nuevo marshaller para cada operación de marshalling, con un comentario javadoc en el código que dice que los marshallers de JAXB no son necesariamente seguros para subprocesos.
Lo mismo se dice en esta página: https://javaee.github.io/jaxb-v2/doc/user-guide/ch03.html#other-mistionary-topics-performance-and-thread-safety .
Supongo que crear un JAXBContext es una operación costosa, porque implica escanear clases y paquetes en busca de anotaciones. Pero medirlo es la mejor manera de saberlo.
fuente
JAXB 2.2 ( JSR-222 ) tiene esto que decir, en la sección "4.2 JAXBContext":
Desafortunadamente, la especificación no hace ninguna afirmación con respecto a la seguridad de subprocesos de
Unmarshaller
yMarshaller
. Por lo que es mejor asumir que no lo son.fuente
Resolví este problema usando:
fuente
¡¡Aun mejor!! Según la buena solución de la publicación anterior, cree el contexto solo una vez en el constructor y guárdelo en lugar de la clase.
Reemplazar la línea:
Con este:
Y el constructor principal con este:
entonces en getMarshaller / getUnmarshaller puede eliminar esta línea:
Esta mejora hace, en mi caso, que los tiempos de procesamiento bajen de 60 ~ 70ms a solo 5 ~ 10ms
fuente
Normalmente resuelvo problemas como este con un
ThreadLocal
patrón de clase. Dado que necesita un marshaller diferente para cada clase, puede combinarlo con unsingleton
patrón -map.Para ahorrarle 15 minutos de trabajo. Aquí sigue mi implementación de una fábrica segura para subprocesos para Jaxb Marshallers y Unmarshallers.
Le permite acceder a las instancias de la siguiente manera ...
Y el código que necesitará es una pequeña clase Jaxb que tiene el siguiente aspecto:
fuente