diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/DeserializerCache.java b/src/main/java/com/fasterxml/jackson/databind/deser/DeserializerCache.java index 032723c814..28127c1af0 100644 --- a/src/main/java/com/fasterxml/jackson/databind/deser/DeserializerCache.java +++ b/src/main/java/com/fasterxml/jackson/databind/deser/DeserializerCache.java @@ -1,6 +1,7 @@ package com.fasterxml.jackson.databind.deser; import java.util.HashMap; +import java.util.concurrent.locks.ReentrantLock; import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.databind.*; @@ -52,6 +53,12 @@ public final class DeserializerCache protected final HashMap> _incompleteDeserializers = new HashMap>(8); + + /** + * We hold an explicit lock while creating deserializers to avoid creating duplicates. + */ + private final ReentrantLock _incompleteDeserializersLock = new ReentrantLock(); + /* /********************************************************** /* Life-cycle @@ -246,7 +253,9 @@ protected JsonDeserializer _createAndCacheValueDeserializer(Deserializat * limitations necessary to ensure that only completely initialized ones * are visible and used. */ - synchronized (_incompleteDeserializers) { + try { + _incompleteDeserializersLock.lock(); + // Ok, then: could it be that due to a race condition, deserializer can now be found? JsonDeserializer deser = _findCachedDeserializer(type); if (deser != null) { @@ -269,6 +278,8 @@ protected JsonDeserializer _createAndCacheValueDeserializer(Deserializat _incompleteDeserializers.clear(); } } + } finally { + _incompleteDeserializersLock.unlock(); } }