diff --git a/geowebcache/core/src/main/java/org/geowebcache/locks/MemoryLockProvider.java b/geowebcache/core/src/main/java/org/geowebcache/locks/MemoryLockProvider.java index e97cf3132..55a814c2a 100644 --- a/geowebcache/core/src/main/java/org/geowebcache/locks/MemoryLockProvider.java +++ b/geowebcache/core/src/main/java/org/geowebcache/locks/MemoryLockProvider.java @@ -14,21 +14,47 @@ */ package org.geowebcache.locks; +import org.geotools.util.logging.Logging; + import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.locks.ReentrantLock; import java.util.logging.Level; import java.util.logging.Logger; -import org.geotools.util.logging.Logging; /** - * An in memory lock provider based on a striped lock + * An in memory lock provider. + *
+ * This provider does not constrain the number of locks that can be held at any given time. + * Because any one thread can hold multiple locks at a time, a more appropriate approach + * to constraining resource usage would be to limit the number of concurrent threads instead. + *
+ * One objective of this class is to support + * nested locking scenarios. This class used to use a striped lock algorithm which + * would cause deadlocks for nested locking because of the non-predictable manner in + * which any lock can be arbitrarily locked by another unrelated lock. An example use case of + * nested locks, in pseudocode, would be: + *
+ * lock(metatile); + * try { + * for(tile : metatile.getTiles()){ + * lock(tile); + * try{ + * ... do work + * } finally { + * release(tile); + * } + * } + * } finally { + * release(metatile); + * } + ** * @author Andrea Aime - GeoSolutions */ public class MemoryLockProvider implements LockProvider { - private static Logger LOGGER = Logging.getLogger(MemoryLockProvider.class.getName()); + private final static Logger LOGGER = Logging.getLogger(MemoryLockProvider.class.getName()); ConcurrentHashMap