Author: davsclaus Date: Wed Feb 15 19:07:55 2012 New Revision: 1244648 URL: http://svn.apache.org/viewvc?rev=1244648&view=rev Log: CAMEL-5002: Improved type converter lookup to avoid synchronization.
Added: camel/branches/camel-2.9.x/camel-core/src/test/java/org/apache/camel/issues/MyCamelBean.java - copied unchanged from r1244644, camel/trunk/camel-core/src/test/java/org/apache/camel/issues/MyCamelBean.java camel/branches/camel-2.9.x/camel-core/src/test/java/org/apache/camel/issues/TypeConverterConcurrencyIssueTest.java - copied unchanged from r1244644, camel/trunk/camel-core/src/test/java/org/apache/camel/issues/TypeConverterConcurrencyIssueTest.java Modified: camel/branches/camel-2.9.x/ (props changed) camel/branches/camel-2.9.x/camel-core/src/main/java/org/apache/camel/impl/converter/BaseTypeConverterRegistry.java Propchange: camel/branches/camel-2.9.x/ ------------------------------------------------------------------------------ --- svn:mergeinfo (original) +++ svn:mergeinfo Wed Feb 15 19:07:55 2012 @@ -1 +1 @@ -/camel/trunk:1243046,1243057,1243234,1244518 +/camel/trunk:1243046,1243057,1243234,1244518,1244644 Propchange: camel/branches/camel-2.9.x/ ------------------------------------------------------------------------------ Binary property 'svnmerge-integrated' - no diff available. Modified: camel/branches/camel-2.9.x/camel-core/src/main/java/org/apache/camel/impl/converter/BaseTypeConverterRegistry.java URL: http://svn.apache.org/viewvc/camel/branches/camel-2.9.x/camel-core/src/main/java/org/apache/camel/impl/converter/BaseTypeConverterRegistry.java?rev=1244648&r1=1244647&r2=1244648&view=diff ============================================================================== --- camel/branches/camel-2.9.x/camel-core/src/main/java/org/apache/camel/impl/converter/BaseTypeConverterRegistry.java (original) +++ camel/branches/camel-2.9.x/camel-core/src/main/java/org/apache/camel/impl/converter/BaseTypeConverterRegistry.java Wed Feb 15 19:07:55 2012 @@ -52,7 +52,7 @@ import org.slf4j.LoggerFactory; */ public abstract class BaseTypeConverterRegistry extends ServiceSupport implements TypeConverter, TypeConverterRegistry { protected final transient Logger log = LoggerFactory.getLogger(getClass()); - protected final Map<TypeMapping, TypeConverter> typeMappings = new ConcurrentHashMap<TypeMapping, TypeConverter>(); + protected final ConcurrentHashMap<TypeMapping, TypeConverter> typeMappings = new ConcurrentHashMap<TypeMapping, TypeConverter>(); protected final Map<TypeMapping, TypeMapping> misses = new ConcurrentHashMap<TypeMapping, TypeMapping>(); protected final List<TypeConverterLoader> typeConverterLoaders = new ArrayList<TypeConverterLoader>(); protected final List<FallbackTypeConverter> fallbackConverters = new ArrayList<FallbackTypeConverter>(); @@ -237,18 +237,16 @@ public abstract class BaseTypeConverterR public void addTypeConverter(Class<?> toType, Class<?> fromType, TypeConverter typeConverter) { log.trace("Adding type converter: {}", typeConverter); TypeMapping key = new TypeMapping(toType, fromType); - synchronized (typeMappings) { - TypeConverter converter = typeMappings.get(key); - // only override it if its different - // as race conditions can lead to many threads trying to promote the same fallback converter - if (typeConverter != converter) { - if (converter != null) { - log.warn("Overriding type converter from: " + converter + " to: " + typeConverter); - } - typeMappings.put(key, typeConverter); - // remove any previous misses, as we added the new type converter - misses.remove(key); + TypeConverter converter = typeMappings.get(key); + // only override it if its different + // as race conditions can lead to many threads trying to promote the same fallback converter + if (typeConverter != converter) { + if (converter != null) { + log.warn("Overriding type converter from: " + converter + " to: " + typeConverter); } + typeMappings.put(key, typeConverter); + // remove any previous misses, as we added the new type converter + misses.remove(key); } } @@ -281,22 +279,18 @@ public abstract class BaseTypeConverterR public Set<Class<?>> getFromClassMappings() { Set<Class<?>> answer = new HashSet<Class<?>>(); - synchronized (typeMappings) { - for (TypeMapping mapping : typeMappings.keySet()) { - answer.add(mapping.getFromType()); - } + for (TypeMapping mapping : typeMappings.keySet()) { + answer.add(mapping.getFromType()); } return answer; } public Map<Class<?>, TypeConverter> getToClassMappings(Class<?> fromClass) { Map<Class<?>, TypeConverter> answer = new HashMap<Class<?>, TypeConverter>(); - synchronized (typeMappings) { - for (Map.Entry<TypeMapping, TypeConverter> entry : typeMappings.entrySet()) { - TypeMapping mapping = entry.getKey(); - if (mapping.isApplicable(fromClass)) { - answer.put(mapping.getToType(), entry.getValue()); - } + for (Map.Entry<TypeMapping, TypeConverter> entry : typeMappings.entrySet()) { + TypeMapping mapping = entry.getKey(); + if (mapping.isApplicable(fromClass)) { + answer.put(mapping.getToType(), entry.getValue()); } } return answer; @@ -312,14 +306,12 @@ public abstract class BaseTypeConverterR fromType = value.getClass(); } TypeMapping key = new TypeMapping(toType, fromType); - TypeConverter converter; - synchronized (typeMappings) { - converter = typeMappings.get(key); - if (converter == null) { - converter = lookup(toType, fromType); - if (converter != null) { - typeMappings.put(key, converter); - } + TypeConverter converter = typeMappings.get(key); + if (converter == null) { + // converter not found, try to lookup then + converter = lookup(toType, fromType); + if (converter != null) { + typeMappings.putIfAbsent(key, converter); } } return converter;