On 06/12/11 07:13, Charles Oliver Nutter wrote:
I'm trying to reimplement JRuby's version of Ruby's Mutex class, a
non-reentrant locking mechanism. One of the properties of a Mutex is
that when the thread holding its lock dies, the lock is released:


You can copy/paste/hack the Mutex example from our
AbstractQueuedSynchronizer javadoc:
http://download.oracle.com/javase/7/docs/api/java/util/concurrent/locks/AbstractQueuedSynchronizer.html
Also pasted below. This version does not perform ownership checks
etc so you can safely unlock on finalization (or whatever).
(Disagreements about whether we should expose something so
abusable led to it being inside javadoc vs an actual exported class.
One of these days we should reconsider this.) Yet it does
still generate monitoring-and-management information when
threads actually block, so most problems are diagnosable,
although there is no automatic cyclic-wait deadlock detection.


 class Mutex implements Lock, java.io.Serializable {

   // Our internal helper class
   private static class Sync extends AbstractQueuedSynchronizer {
     // Report whether in locked state
     protected boolean isHeldExclusively() {
       return getState() == 1;
     }

     // Acquire the lock if state is zero
     public boolean tryAcquire(int acquires) {
       assert acquires == 1; // Otherwise unused
       if (compareAndSetState(0, 1)) {
         setExclusiveOwnerThread(Thread.currentThread());
         return true;
       }
       return false;
     }

     // Release the lock by setting state to zero
     protected boolean tryRelease(int releases) {
       assert releases == 1; // Otherwise unused
       if (getState() == 0) throw new IllegalMonitorStateException();
       setExclusiveOwnerThread(null);
       setState(0);
       return true;
     }

     // Provide a Condition
     Condition newCondition() { return new ConditionObject(); }

     // Deserialize properly
     private void readObject(ObjectInputStream s)
         throws IOException, ClassNotFoundException {
       s.defaultReadObject();
       setState(0); // reset to unlocked state
     }
   }

   // The sync object does all the hard work. We just forward to it.
   private final Sync sync = new Sync();

   public void lock()                { sync.acquire(1); }
   public boolean tryLock()          { return sync.tryAcquire(1); }
   public void unlock()              { sync.release(1); }
   public Condition newCondition()   { return sync.newCondition(); }
   public boolean isLocked()         { return sync.isHeldExclusively(); }
   public boolean hasQueuedThreads() { return sync.hasQueuedThreads(); }
   public void lockInterruptibly() throws InterruptedException {
     sync.acquireInterruptibly(1);
   }
   public boolean tryLock(long timeout, TimeUnit unit)
       throws InterruptedException {
     return sync.tryAcquireNanos(1, unit.toNanos(timeout));
   }
 }


--
You received this message because you are subscribed to the Google Groups "JVM 
Languages" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/jvm-languages?hl=en.

Reply via email to