Mercurial > hg > blitz_condensed
diff src/EDU/oswego/cs/dl/util/concurrent/ReentrantLock.java @ 0:3dc0c5604566
Initial checkin of blitz 2.0 fcs - no installer yet.
author | Dan Creswell <dan.creswell@gmail.com> |
---|---|
date | Sat, 21 Mar 2009 11:00:06 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/EDU/oswego/cs/dl/util/concurrent/ReentrantLock.java Sat Mar 21 11:00:06 2009 +0000 @@ -0,0 +1,147 @@ +/* + File: ReentrantLock.java + + Originally written by Doug Lea and released into the public domain. + This may be used for any purposes whatsoever without acknowledgment. + Thanks for the assistance and support of Sun Microsystems Labs, + and everyone contributing, testing, and using this code. + + History: + Date Who What + 11Jun1998 dl Create public version + 5Aug1998 dl replaced int counters with longs +*/ + +package EDU.oswego.cs.dl.util.concurrent; + +/** + * A lock with the same semantics as builtin + * Java synchronized locks: Once a thread has a lock, it + * can re-obtain it any number of times without blocking. + * The lock is made available to other threads when + * as many releases as acquires have occurred. + * <p>[<a href="http://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/intro.html"> Introduction to this package. </a>] +**/ + + +public class ReentrantLock implements Sync { + + protected Thread owner_ = null; + protected long holds_ = 0; + + public void acquire() throws InterruptedException { + if (Thread.interrupted()) throw new InterruptedException(); + Thread caller = Thread.currentThread(); + synchronized(this) { + if (caller == owner_) + ++holds_; + else { + try { + while (owner_ != null) wait(); + owner_ = caller; + holds_ = 1; + } + catch (InterruptedException ex) { + notify(); + throw ex; + } + } + } + } + + + public boolean attempt(long msecs) throws InterruptedException { + if (Thread.interrupted()) throw new InterruptedException(); + Thread caller = Thread.currentThread(); + synchronized(this) { + if (caller == owner_) { + ++holds_; + return true; + } + else if (owner_ == null) { + owner_ = caller; + holds_ = 1; + return true; + } + else if (msecs <= 0) + return false; + else { + long waitTime = msecs; + long start = System.currentTimeMillis(); + try { + for (;;) { + wait(waitTime); + if (caller == owner_) { + ++holds_; + return true; + } + else if (owner_ == null) { + owner_ = caller; + holds_ = 1; + return true; + } + else { + waitTime = msecs - (System.currentTimeMillis() - start); + if (waitTime <= 0) + return false; + } + } + } + catch (InterruptedException ex) { + notify(); + throw ex; + } + } + } + } + + /** + * Release the lock. + * @exception Error thrown if not current owner of lock + **/ + public synchronized void release() { + if (Thread.currentThread() != owner_) + throw new Error("Illegal Lock usage"); + + if (--holds_ == 0) { + owner_ = null; + notify(); + } + } + + /** + * Release the lock N times. <code>release(n)</code> is + * equivalent in effect to: + * <pre> + * for (int i = 0; i < n; ++i) release(); + * </pre> + * <p> + * @exception Error thrown if not current owner of lock + * or has fewer than N holds on the lock + **/ + public synchronized void release(long n) { + if (Thread.currentThread() != owner_ || n > holds_) + throw new Error("Illegal Lock usage"); + + holds_ -= n; + if (holds_ == 0) { + owner_ = null; + notify(); + } + } + + + /** + * Return the number of unreleased acquires performed + * by the current thread. + * Returns zero if current thread does not hold lock. + **/ + public synchronized long holds() { + if (Thread.currentThread() != owner_) return 0; + return holds_; + } + + + +} +