I was wondering if this might be possible, since I notice 
ReentratReadWriteLock's read lock can be unlocked by a different thread.

Thanks Doug, I'll give this a try. In the interim I added a list of held locks 
to the Ruby thread object, to be released on termination...but it feels a 
little icky.

- Charlie (mobile)

On Jun 12, 2011, at 10:10, Doug Lea <[email protected]> wrote:

> 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.
> 

-- 
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