From 9d482b0e3541b31ac0804665e182e8eab4ea64c4 Mon Sep 17 00:00:00 2001 From: mhyeon-lee Date: Fri, 15 May 2020 17:16:47 +0900 Subject: [PATCH] DATACMNS-1706 - Improve locking in PreferredConstructor#isConstructorParameter. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Switch property parameter cache from HashMap and external locks to ConcurrentHashMap to improve multi-threaded locking behavior during isConstructorParameter(…) initialization. Original pull request: #437. --- .../data/mapping/PreferredConstructor.java | 47 ++++++------------- 1 file changed, 14 insertions(+), 33 deletions(-) diff --git a/src/main/java/org/springframework/data/mapping/PreferredConstructor.java b/src/main/java/org/springframework/data/mapping/PreferredConstructor.java index b0fcc938f..a01e462ef 100644 --- a/src/main/java/org/springframework/data/mapping/PreferredConstructor.java +++ b/src/main/java/org/springframework/data/mapping/PreferredConstructor.java @@ -18,11 +18,9 @@ package org.springframework.data.mapping; import java.lang.annotation.Annotation; import java.lang.reflect.Constructor; import java.util.Arrays; -import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReentrantReadWriteLock; +import java.util.concurrent.ConcurrentHashMap; import org.springframework.beans.factory.annotation.Value; import org.springframework.data.annotation.PersistenceConstructor; @@ -42,16 +40,13 @@ import org.springframework.util.StringUtils; * @author Thomas Darimont * @author Christoph Strobl * @author Mark Paluch + * @author Myeonghyeon Lee */ public class PreferredConstructor> { private final Constructor constructor; private final List> parameters; - private final Map, Boolean> isPropertyParameterCache = new HashMap<>(); - - private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); - private final Lock read = lock.readLock(); - private final Lock write = lock.writeLock(); + private final Map, Boolean> isPropertyParameterCache = new ConcurrentHashMap<>(); /** * Creates a new {@link PreferredConstructor} from the given {@link Constructor} and {@link Parameter}s. @@ -128,36 +123,22 @@ public class PreferredConstructor> { Assert.notNull(property, "Property must not be null!"); - try { - - read.lock(); - Boolean cached = isPropertyParameterCache.get(property); - - if (cached != null) { - return cached; - } + Boolean cached = isPropertyParameterCache.get(property); - } finally { - read.unlock(); + if (cached != null) { + return cached; } - try { - - write.lock(); - - for (Parameter parameter : parameters) { - if (parameter.maps(property)) { - isPropertyParameterCache.put(property, true); - return true; - } + boolean result = false; + for (Parameter parameter : parameters) { + if (parameter.maps(property)) { + isPropertyParameterCache.put(property, true); + result = true; + break; } - - isPropertyParameterCache.put(property, false); - return false; - - } finally { - write.unlock(); } + + return result; } /**