Pytanie jest trochę teoretyczne, jaki jest koszt stworzenia kontekstu JAXB, marshallera i unmarshaller?
Zauważyłem, że mój kod mógłby skorzystać na zachowaniu tego samego kontekstu JAXB i prawdopodobnie tego samego organizatora dla wszystkich operacji kierowania, zamiast tworzenia kontekstu i organizatora na każdym organizowaniu.
Więc jaki jest koszt stworzenia kontekstu JAXB i Marshaller / Unmarshaller? Czy można utworzyć kontekst + organizator dla każdej operacji kierowania, czy lepiej tego uniknąć?
źródło
Najlepiej byłoby, gdybyś miał pojedyncze
JAXBContext
i lokalne wystąpieniaMarshaller
iUnmarshaller
.JAXBContext
wystąpienia są bezpieczne dla wątków,Marshaller
aUnmarshaller
wystąpienia nie są bezpieczne dla wątków i nigdy nie powinny być współużytkowane w wątkach.źródło
Szkoda, że nie jest to szczegółowo opisane w javadoc. Mogę powiedzieć, że Spring używa globalnego JAXBContext, współdzielonego między wątkami, podczas gdy tworzy nowy organizator dla każdej operacji kierowania z komentarzem javadoc w kodzie mówiącym, że organizatory JAXB niekoniecznie są bezpieczne dla wątków.
To samo jest powiedziane na tej stronie: https://javaee.github.io/jaxb-v2/doc/user-guide/ch03.html#other-miscellaneous-topics-performance-and-thread-safety .
Domyślam się, że tworzenie JAXBContext jest kosztowną operacją, ponieważ wiąże się ze skanowaniem klas i pakietów pod kątem adnotacji. Jednak mierzenie tego jest najlepszym sposobem, aby to wiedzieć.
źródło
JAXB 2.2 ( JSR-222 ) ma to do powiedzenia w sekcji „4.2 JAXBContext”:
Niestety specyfikacja nie zawiera żadnych zastrzeżeń dotyczących bezpieczeństwa wątków
Unmarshaller
iMarshaller
. Dlatego najlepiej założyć, że tak nie jest.źródło
Rozwiązałem ten problem używając:
źródło
Nawet lepiej!! Bazując na dobrym rozwiązaniu z powyższego postu, stwórz kontekst tylko raz w konstruktorze i zapisz go zamiast klasy.
Wymień linię:
z tym:
A główny konstruktor z tym:
więc w getMarshaller / getUnmarshaller możesz usunąć tę linię:
To ulepszenie sprawia, że w moim przypadku czas przetwarzania spada z 60 ~ 70 ms do zaledwie 5 ~ 10 ms
źródło
Zazwyczaj rozwiązuję takie problemy za pomocą
ThreadLocal
wzorca klasowego. Biorąc pod uwagę fakt, że potrzebujesz innego koordynatora dla każdej klasy, możesz połączyć go zesingleton
wzorem -mapy.Aby zaoszczędzić 15 minut pracy. Oto moja implementacja bezpiecznej wątkowo fabryki dla Jaxb Marshallers i Unmarshallers.
Umożliwia dostęp do instancji w następujący sposób ...
Kod, którego będziesz potrzebować, to mała klasa Jaxb, która wygląda następująco:
źródło