44import java .lang .reflect .Constructor ;
55import java .lang .reflect .InvocationTargetException ;
66import java .util .*;
7+ import java .util .concurrent .ConcurrentHashMap ;
78
89import com .fasterxml .jackson .annotation .*;
910
@@ -177,8 +178,9 @@ public abstract class BeanDeserializerBase
177178 * Note that this is <b>only needed</b> for polymorphic types,
178179 * that is, when the actual type is not statically known.
179180 * For other types this remains null.
181+ * The map type changed in 2.18 (from HashMap to ConcurrentHashMap)
180182 */
181- protected transient HashMap <ClassKey , JsonDeserializer <Object >> _subDeserializers ;
183+ protected transient ConcurrentHashMap <ClassKey , JsonDeserializer <Object >> _subDeserializers ;
182184
183185 /**
184186 * If one of properties has "unwrapped" value, we need separate
@@ -1882,17 +1884,14 @@ protected JsonDeserializer<Object> _findSubclassDeserializer(DeserializationCont
18821884 Object bean , TokenBuffer unknownTokens )
18831885 throws IOException
18841886 {
1885- JsonDeserializer <Object > subDeser ;
1886-
18871887 // First: maybe we have already created sub-type deserializer?
1888- synchronized (this ) {
1889- subDeser = (_subDeserializers == null ) ? null : _subDeserializers .get (new ClassKey (bean .getClass ()));
1890- }
1888+ final ClassKey classKey = new ClassKey (bean .getClass ());
1889+ JsonDeserializer <Object > subDeser = (_subDeserializers == null ) ? null : _subDeserializers .get (classKey );
18911890 if (subDeser != null ) {
18921891 return subDeser ;
18931892 }
18941893 // If not, maybe we can locate one. First, need provider
1895- JavaType type = ctxt .constructType (bean .getClass ());
1894+ final JavaType type = ctxt .constructType (bean .getClass ());
18961895 /* 30-Jan-2012, tatu: Ideally we would be passing referring
18971896 * property; which in theory we could keep track of via
18981897 * ResolvableDeserializer (if we absolutely must...).
@@ -1902,12 +1901,14 @@ protected JsonDeserializer<Object> _findSubclassDeserializer(DeserializationCont
19021901 subDeser = ctxt .findRootValueDeserializer (type );
19031902 // Also, need to cache it
19041903 if (subDeser != null ) {
1905- synchronized (this ) {
1906- if (_subDeserializers == null ) {
1907- _subDeserializers = new HashMap <ClassKey ,JsonDeserializer <Object >>();;
1904+ if (_subDeserializers == null ) {
1905+ synchronized (this ) {
1906+ if (_subDeserializers == null ) {
1907+ _subDeserializers = new ConcurrentHashMap <>();
1908+ }
19081909 }
1909- _subDeserializers .put (new ClassKey (bean .getClass ()), subDeser );
19101910 }
1911+ _subDeserializers .put (classKey , subDeser );
19111912 }
19121913 return subDeser ;
19131914 }
0 commit comments