# HG changeset patch
# Parent fca2785ddde35f1a52ccf710169f41d26f72a3c9

diff --git a/drools-core/src/main/java/org/drools/base/ClassFieldAccessorCache.java b/drools-core/src/main/java/org/drools/base/ClassFieldAccessorCache.java
--- a/drools-core/src/main/java/org/drools/base/ClassFieldAccessorCache.java
+++ b/drools-core/src/main/java/org/drools/base/ClassFieldAccessorCache.java
@@ -1,9 +1,10 @@
 package org.drools.base;
 
 import java.security.ProtectionDomain;
-import java.util.HashMap;
 import java.util.Map;
 import java.util.WeakHashMap;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
 
 import org.drools.RuntimeDroolsException;
 import org.drools.util.asm.ClassFieldInspector;
@@ -290,12 +291,12 @@ public class ClassFieldAccessorCache {
 
     public static class CacheEntry {
         private ByteArrayClassLoader                         byteArrayClassLoader;
-        private final Map<AccessorKey, BaseClassFieldReader> readCache   = new HashMap<AccessorKey, BaseClassFieldReader>();
-        private final Map<AccessorKey, BaseClassFieldWriter> writeCache  = new HashMap<AccessorKey, BaseClassFieldWriter>();
+        private final ConcurrentMap<AccessorKey, BaseClassFieldReader> readCache   = new ConcurrentHashMap<AccessorKey, BaseClassFieldReader>();
+        private final ConcurrentMap<AccessorKey, BaseClassFieldWriter> writeCache  = new ConcurrentHashMap<AccessorKey, BaseClassFieldWriter>();
 
-        private final Map<Class< ? >, ClassFieldInspector>   inspectors  = new HashMap<Class< ? >, ClassFieldInspector>();
+        private final ConcurrentMap<Class< ? >, ClassFieldInspector>   inspectors  = new ConcurrentHashMap<Class< ? >, ClassFieldInspector>();
 
-        private final Map<ClassObjectTypeKey, ClassObjectType>       objectTypes = new HashMap<ClassObjectTypeKey, ClassObjectType>();
+        private final ConcurrentMap<ClassObjectTypeKey, ClassObjectType>       objectTypes = new ConcurrentHashMap<ClassObjectTypeKey, ClassObjectType>();
 
         public CacheEntry(ClassLoader parentClassLoader) {
             if ( parentClassLoader == null ) {
@@ -315,8 +316,12 @@ public class ClassFieldAccessorCache {
                 reader = ClassFieldAccessorFactory.getInstance().getClassFieldReader( cls,
                                                                                       key.getFieldName(),
                                                                                       this );
-                this.readCache.put( key,
-                                    reader );
+                BaseClassFieldReader existingReader = this.readCache.putIfAbsent( key,
+                                                                                  reader );
+                if ( existingReader != null ) {
+                    // Raced, use the (now) existing entry
+                    reader = existingReader;
+                }
             }
 
             return reader;
@@ -324,16 +329,20 @@ public class ClassFieldAccessorCache {
 
         public BaseClassFieldWriter getWriteAccessor(AccessorKey key,
                                                      Class cls) {
-            BaseClassFieldWriter reader = this.writeCache.get( key );
-            if ( reader == null ) {
-                reader = ClassFieldAccessorFactory.getInstance().getClassFieldWriter( cls,
+            BaseClassFieldWriter writer = this.writeCache.get( key );
+            if ( writer == null ) {
+                writer = ClassFieldAccessorFactory.getInstance().getClassFieldWriter( cls,
                                                                                       key.getFieldName(),
                                                                                       this );
-                this.writeCache.put( key,
-                                     reader );
+                BaseClassFieldWriter existingWriter = this.writeCache.putIfAbsent( key,
+                                                                                   writer );
+                if ( existingWriter != null ) {
+                    // Raced, use the (now) existing entry
+                    writer = existingWriter;
+                }
             }
 
-            return reader;
+            return writer;
         }
 
         public Map<Class< ? >, ClassFieldInspector> getInspectors() {
@@ -344,14 +353,16 @@ public class ClassFieldAccessorCache {
             ClassObjectTypeKey key = new ClassObjectTypeKey(cls, objectType.isEvent() );            
             ClassObjectType existing = objectTypes.get( key );
             
-            if ( existing != null ) {
-                objectType = existing;
-            } else {
+            if ( existing == null ) {
                 objectType.setClassType( cls ); // most likely set, but set anyway.
-                objectTypes.put(  key, objectType );
+                existing = objectTypes.put(  key, objectType );
+                if ( existing == null ) {
+                    // Not raced, use the one we created.
+                    existing = objectType;
+                }
             }
             
-            return objectType;            
+            return existing;            
         }
 
     }
diff --git a/drools-core/src/main/java/org/drools/common/ObjectTypeConfigurationRegistry.java b/drools-core/src/main/java/org/drools/common/ObjectTypeConfigurationRegistry.java
--- a/drools-core/src/main/java/org/drools/common/ObjectTypeConfigurationRegistry.java
+++ b/drools-core/src/main/java/org/drools/common/ObjectTypeConfigurationRegistry.java
@@ -2,8 +2,8 @@ package org.drools.common;
 
 import java.io.Serializable;
 import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
 
 import org.drools.facttemplates.Fact;
 import org.drools.reteoo.ClassObjectTypeConf;
@@ -13,14 +13,14 @@ import org.drools.rule.EntryPoint;
 
 public class ObjectTypeConfigurationRegistry implements Serializable {
     private InternalRuleBase ruleBase;
-    private Map<Object, ObjectTypeConf> typeConfMap;
+    private ConcurrentMap<Object, ObjectTypeConf> typeConfMap;
     
 
     
     public ObjectTypeConfigurationRegistry(InternalRuleBase ruleBase ) {
         super();
         this.ruleBase = ruleBase;
-        this.typeConfMap = new HashMap<Object, ObjectTypeConf>();
+        this.typeConfMap = new ConcurrentHashMap<Object, ObjectTypeConf>();
     }
 
 
@@ -37,29 +37,30 @@ public class ObjectTypeConfigurationRegi
         
         // first see if it's a ClassObjectTypeConf        
         ObjectTypeConf objectTypeConf = null;
-        Class cls = null;
+        Object key;
         if ( object instanceof Fact ) {
-            String key = ((Fact) object).getFactTemplate().getName();
-            objectTypeConf = (ObjectTypeConf) this.typeConfMap.get( key );            
+            key = ((Fact) object).getFactTemplate().getName();
         } else {
-            cls = object.getClass();
-            objectTypeConf = this.typeConfMap.get( cls );            
+            key = object.getClass();
         }                       
+        objectTypeConf = this.typeConfMap.get( key );            
         
         // it doesn't exist, so create it.
         if ( objectTypeConf == null ) {
-            if ( object instanceof Fact ) {;
+            if ( object instanceof Fact ) {
                 objectTypeConf = new FactTemplateTypeConf( entrypoint,
                                                            ((Fact) object).getFactTemplate(),
-                                                           this.ruleBase );           
-                this.typeConfMap.put( ((Fact) object).getFactTemplate().getName(), 
-                                      objectTypeConf );
+                                                           this.ruleBase );
             } else {
                 objectTypeConf = new ClassObjectTypeConf( entrypoint,
-                                                          cls,
+                                                          object.getClass(),
                                                           this.ruleBase );
-                this.typeConfMap.put( cls, objectTypeConf );
-            }            
+            }
+            ObjectTypeConf existing = this.typeConfMap.putIfAbsent( key, objectTypeConf );
+            if ( existing != null ) {
+                // Raced, take the (now) existing.
+                objectTypeConf = existing;
+            }
         }
 
         return objectTypeConf;
diff --git a/drools-core/src/main/java/org/drools/reteoo/EntryPointNode.java b/drools-core/src/main/java/org/drools/reteoo/EntryPointNode.java
--- a/drools-core/src/main/java/org/drools/reteoo/EntryPointNode.java
+++ b/drools-core/src/main/java/org/drools/reteoo/EntryPointNode.java
@@ -22,8 +22,8 @@ import java.io.Externalizable;
 import java.io.IOException;
 import java.io.ObjectInput;
 import java.io.ObjectOutput;
-import java.util.HashMap;
 import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
 
 import org.drools.base.ShadowProxy;
 import org.drools.common.BaseNode;
@@ -101,7 +101,7 @@ public class EntryPointNode extends Obje
                objectSource,
                999 ); // irrelevant for this node, since it overrides sink management
         this.entryPoint = entryPoint;
-        this.objectTypeNodes = new HashMap<ObjectType, ObjectTypeNode>();
+        this.objectTypeNodes = new ConcurrentHashMap<ObjectType, ObjectTypeNode>();
     }
 
     // ------------------------------------------------------------
