[jbosscache-commits] JBoss Cache SVN: r7921 - core/branches/flat/src/main/java/org/horizon/util/concurrent/locks/containers.

jbosscache-commits at lists.jboss.org jbosscache-commits at lists.jboss.org
Thu Mar 19 06:06:23 EDT 2009


Author: manik.surtani at jboss.com
Date: 2009-03-19 06:06:23 -0400 (Thu, 19 Mar 2009)
New Revision: 7921

Modified:
   core/branches/flat/src/main/java/org/horizon/util/concurrent/locks/containers/AbstractPerEntryLockContainer.java
Log:
HORIZON-40 - Create a lock-per-entry lock manager

Modified: core/branches/flat/src/main/java/org/horizon/util/concurrent/locks/containers/AbstractPerEntryLockContainer.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/util/concurrent/locks/containers/AbstractPerEntryLockContainer.java	2009-03-19 09:59:50 UTC (rev 7920)
+++ core/branches/flat/src/main/java/org/horizon/util/concurrent/locks/containers/AbstractPerEntryLockContainer.java	2009-03-19 10:06:23 UTC (rev 7921)
@@ -17,11 +17,14 @@
 
    protected abstract Lock newLock();
 
-   public Lock getLock(Object key) {
-      Lock l = newLock();
-      Lock tmp = locks.putIfAbsent(key, l);
-      if (tmp != null) l = tmp;
-      return l;
+   public final Lock getLock(Object key) {
+      // this is an optimisation.  It is not foolproof as we may still be creating new locks unnecessarily (thrown away
+      // when we do a putIfAbsent) but it minimises the chances somewhat, for the cost of an extra CHM get.
+      Lock lock = locks.get(key);
+      if (lock == null) lock = newLock();
+      Lock existingLock = locks.putIfAbsent(key, lock);
+      if (existingLock != null) lock = existingLock;
+      return lock;
    }
 
    public int getNumLocksHeld() {
@@ -33,13 +36,23 @@
    }
 
    public boolean acquireLock(Object key, long timeout, TimeUnit unit) throws InterruptedException {
-      Lock l = getLock(key);
-      boolean success = l.tryLock(timeout, unit);
-      if (l != locks.get(key)) {
-         l.unlock();
-         success = acquireLock(key, timeout, unit); // todo avoid recursion here, this could get ugly!
+      while (true) {
+         Lock lock = getLock(key);
+         if (lock.tryLock(timeout, unit)) {
+            // lock acquired.  Now check if it is the *correct* lock!
+            Lock existingLock = locks.putIfAbsent(key, lock);
+            if (existingLock != null && existingLock != lock) {
+               // we have the wrong lock!  Unlock and retry.
+               lock.unlock();
+            } else {
+               // we got the right lock.
+               return true;
+            }
+         } else {
+            // we couldn't acquire the lock within the timeout period
+            return false;
+         }
       }
-      return success;
    }
 
    public void releaseLock(Object key) {




More information about the jbosscache-commits mailing list