| java.lang.Object net.sf.ehcache.constructs.concurrent.Mutex
Mutex | public class Mutex implements Sync(Code) | | version: $Id: Mutex.java 519 2007-07-27 07:11:45Z gregluck $ author: Doug Lea author: A simple non-reentrant mutual exclusion lock. author: The lock is free upon construction. Each acquire gets the author: lock, and each release frees it. Releasing a lock that author: is already free has no effect. author: author: This implementation makes no attempt to provide any fairness author: or ordering guarantees. If you need them, consider using one of author: the Semaphore implementations as a locking mechanism. author: author: Sample usage
author: author: Mutex can be useful in constructions that cannot be author: expressed using java synchronized blocks because the author: acquire/release pairs do not occur in the same method or author: code block. For example, you can use them for hand-over-hand author: locking across the nodes of a linked list. This allows author: extremely fine-grained locking, and so increases author: potential concurrency, at the cost of additional complexity and author: overhead that would normally make this worthwhile only in cases of author: extreme contention. author: author: class Node { author: Object item; author: Node next; author: Mutex lock = new Mutex(); // each node keeps its own lock author: author: Node(Object x, Node n) { item = x; next = n; } author: } author: author: class List { author: protected Node head; // pointer to first node of list author: author: // Use plain java synchronization to protect head field. author: // (We could instead use a Mutex here too but there is no author: // reason to do so.) author: protected synchronized Node getHead() { return head; } author: author: boolean search(Object x) throws InterruptedException { author: Node p = getHead(); author: if (p == null) return false; author: author: // (This could be made more compact, but for clarity of illustration, author: // all of the cases that can arise are handled separately.) author: author: p.lock.acquire(); // Prime loop by acquiring first lock. author: // (If the acquire fails due to author: // interrupt, the method will throw author: // InterruptedException now, author: // so there is no need for any author: // further cleanup.) author: for (;;) { author: if (x.equals(p.item)) { author: p.lock.release(); // release current before return author: return true; author: } author: else { author: Node nextp = p.next; author: if (nextp == null) { author: p.lock.release(); // release final lock that was held author: return false; author: } author: else { author: try { author: nextp.lock.acquire(); // get next lock before releasing current author: } author: catch (InterruptedException ex) { author: p.lock.release(); // also release current if acquire fails author: throw ex; author: } author: p.lock.release(); // release old lock now that new one held author: p = nextp; author: } author: } author: } author: } author: author: synchronized void add(Object x) { // simple prepend author: // The use of `synchronized' here protects only head field. author: // The method does not need to wait out other traversers author: // who have already made it past head. author: author: head = new Node(x, head); author: } author: author: // ... other similar traversal and update methods ... author: } author:
author: author: [ Introduction to this package. ] |
Field Summary | |
protected boolean | inUse |
Method Summary | |
public void | acquire() Wait (possibly forever) until successful passage.
Fail only upon interuption. | public boolean | attempt(long msecs) Parameters: msecs - the number of milleseconds to wait.An argument less than or equal to zero means not to wait at all.However, this may still requireaccess to a synchronization lock, which can impose unboundeddelay if there is a lot of contention among threads. | public synchronized void | release() Potentially enable others to pass.
Because release does not raise exceptions,
it can be used in `finally' clauses without requiring extra
embedded try/catch blocks. |
inUse | protected boolean inUse(Code) | | The lock status *
|
acquire | public void acquire() throws InterruptedException(Code) | | Wait (possibly forever) until successful passage.
Fail only upon interuption. Interruptions always result in
`clean' failures. On failure, you can be sure that it has not
been acquired, and that no
corresponding release should be performed. Conversely,
a normal return guarantees that the acquire was successful.
See Also: Sync.acquire See Also: |
attempt | public boolean attempt(long msecs) throws InterruptedException(Code) | | Parameters: msecs - the number of milleseconds to wait.An argument less than or equal to zero means not to wait at all.However, this may still requireaccess to a synchronization lock, which can impose unboundeddelay if there is a lot of contention among threads. true if acquired See Also: Sync.attempt(long) |
release | public synchronized void release()(Code) | | Potentially enable others to pass.
Because release does not raise exceptions,
it can be used in `finally' clauses without requiring extra
embedded try/catch blocks. But keep in mind that
as with any java method, implementations may
still throw unchecked exceptions such as Error or NullPointerException
when faced with uncontinuable errors. However, these should normally
only be caught by higher-level error handlers.
See Also: Sync.release |
|
|