| ||||
|
Code - Class EDU.oswego.cs.dl.util.concurrent.Mutex1 /* 2 File: Mutex.java 3 4 Originally written by Doug Lea and released into the public domain. 5 This may be used for any purposes whatsoever without acknowledgment. 6 Thanks for the assistance and support of Sun Microsystems Labs, 7 and everyone contributing, testing, and using this code. 8 9 History: 10 Date Who What 11 11Jun1998 dl Create public version 12 */ 13 14 package EDU.oswego.cs.dl.util.concurrent; 15 16 /** 17 * A simple non-reentrant mutual exclusion lock. 18 * The lock is free upon construction. Each acquire gets the 19 * lock, and each release frees it. Releasing a lock that 20 * is already free has no effect. 21 * <p> 22 * This implementation makes no attempt to provide any fairness 23 * or ordering guarantees. If you need them, consider using one of 24 * the Semaphore implementations as a locking mechanism. 25 * <p> 26 * <b>Sample usage</b><br> 27 * <p> 28 * Mutex can be useful in constructions that cannot be 29 * expressed using java synchronized blocks because the 30 * acquire/release pairs do not occur in the same method or 31 * code block. For example, you can use them for hand-over-hand 32 * locking across the nodes of a linked list. This allows 33 * extremely fine-grained locking, and so increases 34 * potential concurrency, at the cost of additional complexity and 35 * overhead that would normally make this worthwhile only in cases of 36 * extreme contention. 37 * <pre> 38 * class Node { 39 * Object item; 40 * Node next; 41 * Mutex lock = new Mutex(); // each node keeps its own lock 42 * 43 * Node(Object x, Node n) { item = x; next = n; } 44 * } 45 * 46 * class List { 47 * protected Node head; // pointer to first node of list 48 * 49 * // Use plain java synchronization to protect head field. 50 * // (We could instead use a Mutex here too but there is no 51 * // reason to do so.) 52 * protected synchronized Node getHead() { return head; } 53 * 54 * boolean search(Object x) throws InterruptedException { 55 * Node p = getHead(); 56 * if (p == null) return false; 57 * 58 * // (This could be made more compact, but for clarity of illustration, 59 * // all of the cases that can arise are handled separately.) 60 * 61 * p.lock.acquire(); // Prime loop by acquiring first lock. 62 * // (If the acquire fails due to 63 * // interrupt, the method will throw 64 * // InterruptedException now, 65 * // so there is no need for any 66 * // further cleanup.) 67 * for (;;) { 68 * if (x.equals(p.item)) { 69 * p.lock.release(); // release current before return 70 * return true; 71 * } 72 * else { 73 * Node nextp = p.next; 74 * if (nextp == null) { 75 * p.lock.release(); // release final lock that was held 76 * return false; 77 * } 78 * else { 79 * try { 80 * nextp.lock.acquire(); // get next lock before releasing current 81 * } 82 * catch (InterruptedException ex) { 83 * p.lock.release(); // also release current if acquire fails 84 * throw ex; 85 * } 86 * p.lock.release(); // release old lock now that new one held 87 * p = nextp; 88 * } 89 * } 90 * } 91 * } 92 * 93 * synchronized void add(Object x) { // simple prepend 94 * // The use of `synchronized' here protects only head field. 95 * // The method does not need to wait out other traversers 96 * // who have already made it past head. 97 * 98 * head = new Node(x, head); 99 * } 100 * 101 * // ... other similar traversal and update methods ... 102 * } 103 * </pre> 104 * <p> 105 * @see Semaphore 106 * <p>[<a HREF="http://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/intro.html"> Introduction to this package. </a>] 107 **/ 108 109 public class Mutex implements Sync { 110 111 /** The lock status **/ 112 protected boolean inuse_ = false; 113 114 public void acquire() throws InterruptedException { 115 if (Thread.interrupted()) throw new InterruptedException(); 116 synchronized(this) { 117 try { 118 while (inuse_) wait(); 119 inuse_ = true; 120 } 121 catch (InterruptedException ex) { 122 notify(); 123 throw ex; 124 } 125 } 126 } 127 128 public synchronized void release() { 129 inuse_ = false; 130 notify(); 131 } 132 133 134 public boolean attempt(long msecs) throws InterruptedException { 135 if (Thread.interrupted()) throw new InterruptedException(); 136 synchronized(this) { 137 if (!inuse_) { 138 inuse_ = true; 139 return true; 140 } 141 else if (msecs <= 0) 142 return false; 143 else { 144 long waitTime = msecs; 145 long start = System.currentTimeMillis(); 146 try { 147 for (;;) { 148 wait(waitTime); 149 if (!inuse_) { 150 inuse_ = true; 151 return true; 152 } 153 else { 154 waitTime = msecs - (System.currentTimeMillis() - start); 155 if (waitTime <= 0) 156 return false; 157 } 158 } 159 } 160 catch (InterruptedException ex) { 161 notify(); 162 throw ex; 163 } 164 } 165 } 166 } 167 168 } 169 170 |
|||
Java API By Example, From Geeks To Geeks. |
Conditions of Use |
About Us
© 2002 - 2005, KickJava.com, or its affiliates
|