KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > corba > se > impl > orbutil > concurrent > DebugMutex


1 /*
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 com.sun.corba.se.impl.orbutil.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  * <p>This version adds some debugging capability: it will detect an attempt by a thread
106  * that holds the lock to acquire it for a second time, and also an attempt by a thread that
107  * does not hold the mutex to release it.
108  * @see Semaphore
109  * <p>[<a HREF="http://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/intro.html"> Introduction to this package. </a>]
110 **/

111
112 import org.omg.CORBA.INTERNAL JavaDoc ;
113
114 public class DebugMutex implements Sync {
115
116   /** The lock status **/
117   protected boolean inuse_ = false;
118   protected Thread JavaDoc holder_ = null;
119
120   public void acquire() throws InterruptedException JavaDoc {
121     if (Thread.interrupted()) throw new InterruptedException JavaDoc();
122     synchronized(this) {
123       Thread JavaDoc thr = Thread.currentThread();
124       if (holder_ == thr)
125         throw new INTERNAL JavaDoc(
126         "Attempt to acquire Mutex by thread holding the Mutex" ) ;
127
128       try {
129         while (inuse_) wait();
130         inuse_ = true;
131     holder_ = Thread.currentThread();
132       }
133       catch (InterruptedException JavaDoc ex) {
134         notify();
135         throw ex;
136       }
137     }
138   }
139
140   public synchronized void release() {
141     Thread JavaDoc thr = Thread.currentThread();
142     if (thr != holder_)
143     throw new INTERNAL JavaDoc(
144         "Attempt to release Mutex by thread not holding the Mutex" ) ;
145     holder_ = null;
146     inuse_ = false;
147     notify();
148   }
149
150
151   public boolean attempt(long msecs) throws InterruptedException JavaDoc {
152     if (Thread.interrupted()) throw new InterruptedException JavaDoc();
153     synchronized(this) {
154       Thread JavaDoc thr = Thread.currentThread() ;
155
156       if (!inuse_) {
157         inuse_ = true;
158     holder_ = thr;
159         return true;
160       } else if (msecs <= 0)
161         return false;
162       else {
163         long waitTime = msecs;
164         long start = System.currentTimeMillis();
165         try {
166           for (;;) {
167             wait(waitTime);
168             if (!inuse_) {
169               inuse_ = true;
170           holder_ = thr;
171               return true;
172             }
173             else {
174               waitTime = msecs - (System.currentTimeMillis() - start);
175               if (waitTime <= 0)
176                 return false;
177             }
178           }
179         }
180         catch (InterruptedException JavaDoc ex) {
181           notify();
182           throw ex;
183         }
184       }
185     }
186   }
187 }
188
189
Popular Tags