6323 resource creation deadlock (#6324)
* make map reads concurrent * change log
This commit is contained in:
parent
62fa7ec787
commit
5fe92bd4ef
|
@ -33,6 +33,7 @@ import java.util.Collections;
|
|||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public abstract class BaseRuntimeElementDefinition<T extends IBase> {
|
||||
|
||||
|
@ -40,7 +41,7 @@ public abstract class BaseRuntimeElementDefinition<T extends IBase> {
|
|||
private final Class<? extends T> myImplementingClass;
|
||||
private final String myName;
|
||||
private final boolean myStandardType;
|
||||
private Map<Class<?>, Constructor<T>> myConstructors = Collections.synchronizedMap(new HashMap<>());
|
||||
private final Map<Class<?>, Constructor<T>> myConstructors = new ConcurrentHashMap<>();
|
||||
private List<RuntimeChildDeclaredExtensionDefinition> myExtensions = new ArrayList<>();
|
||||
private List<RuntimeChildDeclaredExtensionDefinition> myExtensionsModifier = new ArrayList<>();
|
||||
private List<RuntimeChildDeclaredExtensionDefinition> myExtensionsNonModifier = new ArrayList<>();
|
||||
|
@ -84,27 +85,24 @@ public abstract class BaseRuntimeElementDefinition<T extends IBase> {
|
|||
argumentType = theArgument.getClass();
|
||||
}
|
||||
|
||||
Constructor<T> retVal = myConstructors.get(argumentType);
|
||||
if (retVal == null) {
|
||||
Constructor<T> retVal = myConstructors.computeIfAbsent(argumentType, type -> {
|
||||
for (Constructor<?> next : getImplementingClass().getConstructors()) {
|
||||
if (argumentType == VOID_CLASS) {
|
||||
if (type == VOID_CLASS) {
|
||||
if (next.getParameterTypes().length == 0) {
|
||||
retVal = (Constructor<T>) next;
|
||||
break;
|
||||
}
|
||||
} else if (next.getParameterTypes().length == 1) {
|
||||
if (next.getParameterTypes()[0].isAssignableFrom(argumentType)) {
|
||||
retVal = (Constructor<T>) next;
|
||||
break;
|
||||
return (Constructor<T>) next;
|
||||
}
|
||||
} else if (next.getParameterTypes().length == 1 && next.getParameterTypes()[0].isAssignableFrom(type)) {
|
||||
return (Constructor<T>) next;
|
||||
}
|
||||
}
|
||||
if (retVal == null) {
|
||||
throw new ConfigurationException(Msg.code(1695) + "Class " + getImplementingClass()
|
||||
+ " has no constructor with a single argument of type " + argumentType);
|
||||
}
|
||||
myConstructors.put(argumentType, retVal);
|
||||
return null;
|
||||
});
|
||||
|
||||
if (retVal == null) {
|
||||
throw new ConfigurationException(Msg.code(1695) + "Class " + getImplementingClass()
|
||||
+ " has no constructor with a single argument of type " + argumentType);
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
type: perf
|
||||
issue: 6323
|
||||
title: "A synchronization choke point was removed from the model object initialization code, reducing the risk of
|
||||
multi-thread contention."
|
Loading…
Reference in New Issue