[jbosscache-commits] JBoss Cache SVN: r6014 - in core/trunk/src/main/java/org/jboss/cache/util/concurrent: locks and 1 other directory.

jbosscache-commits at lists.jboss.org jbosscache-commits at lists.jboss.org
Tue Jun 24 11:23:45 EDT 2008


Author: manik.surtani at jboss.com
Date: 2008-06-24 11:23:45 -0400 (Tue, 24 Jun 2008)
New Revision: 6014

Added:
   core/trunk/src/main/java/org/jboss/cache/util/concurrent/locks/
   core/trunk/src/main/java/org/jboss/cache/util/concurrent/locks/OwnableReentrantLock.java
Log:
Added OwnableReentrantLock

Added: core/trunk/src/main/java/org/jboss/cache/util/concurrent/locks/OwnableReentrantLock.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/util/concurrent/locks/OwnableReentrantLock.java	                        (rev 0)
+++ core/trunk/src/main/java/org/jboss/cache/util/concurrent/locks/OwnableReentrantLock.java	2008-06-24 15:23:45 UTC (rev 6014)
@@ -0,0 +1,188 @@
+package org.jboss.cache.util.concurrent.locks;
+
+import net.jcip.annotations.ThreadSafe;
+import org.jboss.cache.invocation.InvocationContextContainer;
+import org.jboss.cache.transaction.GlobalTransaction;
+
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.AbstractQueuedSynchronizer;
+import java.util.concurrent.locks.Lock;
+
+/**
+ * A lock that supports reentrancy based on owner (and not on current thread).  For this to work, the lock needs to be
+ * constructed with a reference to the {@link org.jboss.cache.invocation.InvocationContextContainer}, so it is able
+ * to determine whether the caller's "owner" reference is the current thread or a {@link org.jboss.cache.transaction.GlobalTransaction}
+ * instance.
+ * <p/>
+ * This makes this lock implementation very closely tied to JBoss Cache internals, but it provides for a very clean, efficient
+ * and moreover familiar interface to work with, since it implements {@link java.util.concurrent.locks.Lock}.
+ * <p/>
+ * For the sake of performance, this lock only supports nonfair queueing.
+ * <p/>
+ *
+ * @author Manik Surtani (<a href="mailto:manik at jboss.org">manik at jboss.org</a>)
+ * @since 3.0
+ */
+ at ThreadSafe
+public class OwnableReentrantLock extends AbstractQueuedSynchronizer implements Lock
+{
+   /**
+    * Current owner
+    */
+   transient Object owner;
+   /**
+    * Invocation context to consult when testing the current requestor
+    */
+   transient InvocationContextContainer invocationContextContainer;
+
+   /**
+    * Creates a new lock instance.
+    *
+    * @param invocationContextContainer InvocationContextContainer instance to consult for the invocation context of the call.
+    */
+   public OwnableReentrantLock(InvocationContextContainer invocationContextContainer)
+   {
+      this.invocationContextContainer = invocationContextContainer;
+   }
+
+   /**
+    * @return a GlobalTransaction instance if the current call is participating in a transaction, or the current thread otherwise.
+    */
+   protected Object currentRequestor()
+   {
+      GlobalTransaction gtx;
+      return (gtx = invocationContextContainer.get().getGlobalTransaction()) == null ? Thread.currentThread() : gtx;
+   }
+
+   public void lock()
+   {
+      if (compareAndSetState(0, 1))
+         owner = currentRequestor();
+      else
+         acquire(1);
+   }
+
+   public void lockInterruptibly() throws InterruptedException
+   {
+      acquireInterruptibly(1);
+   }
+
+   public boolean tryLock()
+   {
+      return tryAcquire(1);
+   }
+
+   public boolean tryLock(long time, TimeUnit unit) throws InterruptedException
+   {
+      return tryAcquireNanos(1, unit.toNanos(time));
+   }
+
+   public void unlock()
+   {
+      release(1);
+   }
+
+   public final ConditionObject newCondition()
+   {
+      return new ConditionObject();
+   }
+
+   @Override
+   protected final boolean tryAcquire(int acquires)
+   {
+      final Object current = currentRequestor();
+      int c = getState();
+      if (c == 0)
+      {
+         if (compareAndSetState(0, acquires))
+         {
+            owner = current;
+            return true;
+         }
+      }
+      else if (current.equals(owner))
+      {
+         setState(c + acquires);
+         return true;
+      }
+      return false;
+   }
+
+   @Override
+   protected final boolean tryRelease(int releases)
+   {
+      int c = getState() - releases;
+      if (!currentRequestor().equals(owner))
+         throw new IllegalMonitorStateException();
+      boolean free = false;
+      if (c == 0)
+      {
+         free = true;
+         owner = null;
+      }
+      setState(c);
+      return free;
+   }
+
+   @Override
+   protected final boolean isHeldExclusively()
+   {
+      return getState() != 0 && currentRequestor().equals(owner);
+   }
+
+   /**
+    * @return the owner of the lock, or null if it is currently unlocked.
+    */
+   public final Object getOwner()
+   {
+      int c = getState();
+      Object o = owner;
+      return (c == 0) ? null : o;
+   }
+
+   /**
+    * @return the hold count of the current lock, or 0 if it is not locked.
+    */
+   public final int getHoldCount()
+   {
+      int c = getState();
+      Object o = owner;
+      return (currentRequestor().equals(o)) ? c : 0;
+   }
+
+   /**
+    * @return true if the lock is locked, false otherwise
+    */
+   public final boolean isLocked()
+   {
+      return getState() != 0;
+   }
+
+   /**
+    * Reconstitute this lock instance from a stream, resetting the lock to an unlocked state.
+    *
+    * @param s the stream
+    */
+   private void readObject(java.io.ObjectInputStream s)
+         throws java.io.IOException, ClassNotFoundException
+   {
+      s.defaultReadObject();
+      setState(0); // reset to unlocked state
+   }
+
+   /**
+    * Returns a string identifying this lock, as well as its lock
+    * state.  The state, in brackets, includes either the String
+    * &quot;Unlocked&quot; or the String &quot;Locked by&quot;
+    * followed by the String representation of the lock owner.
+    *
+    * @return a string identifying this lock, as well as its lock state.
+    */
+   public String toString()
+   {
+      Object owner = getOwner();
+      return super.toString() + ((owner == null) ?
+            "[Unlocked]" :
+            "[Locked by " + owner + "]");
+   }
+}




More information about the jbosscache-commits mailing list