From b2e8e0c5b999cd62cb7ef62bb4898c6c75c64ebf Mon Sep 17 00:00:00 2001 From: Jesse Brault Date: Sun, 4 Jan 2026 18:06:28 -0600 Subject: [PATCH] Fix problems with concurrency. --- build.gradle | 2 +- .../di/AbstractInjectingObjectFactory.java | 32 +++++++++---------- 2 files changed, 16 insertions(+), 18 deletions(-) diff --git a/build.gradle b/build.gradle index 1b07265..a6d7511 100644 --- a/build.gradle +++ b/build.gradle @@ -4,7 +4,7 @@ plugins { } group = 'com.jessebrault.di' -version = '0.1.0' +version = '0.2.0-SNAPSHOT' repositories { mavenCentral() diff --git a/src/main/java/com/jessebrault/di/AbstractInjectingObjectFactory.java b/src/main/java/com/jessebrault/di/AbstractInjectingObjectFactory.java index 8195d41..6236852 100644 --- a/src/main/java/com/jessebrault/di/AbstractInjectingObjectFactory.java +++ b/src/main/java/com/jessebrault/di/AbstractInjectingObjectFactory.java @@ -5,6 +5,7 @@ import org.jetbrains.annotations.Nullable; import java.lang.reflect.*; import java.util.*; +import java.util.concurrent.ConcurrentHashMap; import java.util.function.Consumer; import java.util.stream.Collectors; @@ -104,20 +105,15 @@ public abstract class AbstractInjectingObjectFactory implements ObjectFactory { } - private final Map, Constructor[]> cachedAllConstructors = new HashMap<>(); - private final Collection> cachedInjectConstructors = new ArrayList<>(); - private final Collection> cachedNonInjectConstructors = new ArrayList<>(); - private final Map, Collection> cachedSetters = new HashMap<>(); - private final Map cachedSetterParameters = new HashMap<>(); + private final Map, Constructor[]> cachedAllConstructors = new ConcurrentHashMap<>(); + private final Map, Constructor> cachedInjectConstructors = new ConcurrentHashMap<>(); + private final Map, Map[], Constructor>> cachedNonInjectConstructors = new ConcurrentHashMap<>(); + private final Map, Collection> cachedSetters = new ConcurrentHashMap<>(); + private final Map cachedSetterParameters = new ConcurrentHashMap<>(); @SuppressWarnings("unchecked") private @Nullable Constructor findCachedInjectConstructor(Class clazz) { - for (final CachedInjectConstructor cachedConstructor : this.cachedInjectConstructors) { - if (clazz.equals(cachedConstructor.clazz())) { - return (Constructor) cachedConstructor.constructor(); - } - } - return null; + return (Constructor) this.cachedInjectConstructors.get(clazz); } /** @@ -153,15 +149,14 @@ public abstract class AbstractInjectingObjectFactory implements ObjectFactory { } protected final void putCachedInjectConstructor(CachedInjectConstructor cached) { - this.cachedInjectConstructors.add(cached); + this.cachedInjectConstructors.put(cached.clazz(), cached.constructor()); } @SuppressWarnings("unchecked") private @Nullable Constructor findCachedNonInjectConstructor(Class clazz, Class[] paramTypes) { - for (final CachedNonInjectConstructor cachedConstructor : this.cachedNonInjectConstructors) { - if (clazz.equals(cachedConstructor.clazz()) && Arrays.equals(cachedConstructor.paramTypes(), paramTypes)) { - return (Constructor) cachedConstructor.constructor(); - } + final Map[], Constructor> constructors = this.cachedNonInjectConstructors.get(clazz); + if (constructors != null) { + return (Constructor) constructors.get(paramTypes); } return null; } @@ -209,7 +204,10 @@ public abstract class AbstractInjectingObjectFactory implements ObjectFactory { } protected final void putCachedNonInjectConstructor(CachedNonInjectConstructor cached) { - this.cachedNonInjectConstructors.add(cached); + final Map[], Constructor> constructors = this.cachedNonInjectConstructors.computeIfAbsent( + cached.clazz(), clazz -> new HashMap<>() + ); + constructors.put(cached.paramTypes(), cached.constructor()); } /**