Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/acl/CachingEntryCollector.java
===================================================================
--- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/acl/CachingEntryCollector.java	(revision 1351373)
+++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/acl/CachingEntryCollector.java	(working copy)
@@ -16,6 +16,11 @@
  */
 package org.apache.jackrabbit.core.security.authorization.acl;
 
+import java.util.Map;
+import java.util.concurrent.Semaphore;
+
+import javax.jcr.RepositoryException;
+
 import org.apache.jackrabbit.core.NodeImpl;
 import org.apache.jackrabbit.core.SessionImpl;
 import org.apache.jackrabbit.core.cache.GrowingLRUMap;
@@ -24,9 +29,6 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import javax.jcr.RepositoryException;
-import java.util.Map;
-
 /**
  * <code>CachingEntryCollector</code> extends <code>EntryCollector</code> by
  * keeping a cache of ACEs per access controlled nodeId.
@@ -73,7 +75,7 @@
         Entries entries = cache.get(nodeId);
         if (entries == null) {
             // fetch entries and update the cache
-            entries = updateCache(node);
+            entries = weaklySynchronizedUpdateCache(node);
         }
         return entries;
     }
@@ -87,7 +89,7 @@
         if (entries == null) {
             // fetch entries and update the cache
             NodeImpl n = getNodeById(nodeId);
-            entries = updateCache(n);
+            entries = weaklySynchronizedUpdateCache(n);
         }
         return entries;
     }
@@ -111,6 +113,20 @@
         return entries;
     }
 
+
+    // a variant that only allows sem.permits concurrent updates
+    private Semaphore sem = new Semaphore(4);
+
+    private Entries weaklySynchronizedUpdateCache(NodeImpl node) throws RepositoryException {
+        try {
+            sem.acquireUninterruptibly();
+            Entries r = cache.get(node.getNodeId());
+            return r != null ? r : updateCache(node);
+        } finally {
+            sem.release();
+        }
+    }
+
     /**
      * Find the next access control ancestor in the hierarchy 'null' indicates
      * that there is no ac-controlled ancestor.
