ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/Locks.java
Revision: 1.1
Committed: Wed May 14 21:30:47 2003 UTC (21 years, 1 month ago) by tim
Branch: MAIN
Log Message:
Moved main source rooted at . to ./src/main
Moved test source rooted at ./etc/testcases to ./src/test

File Contents

# Content
1 package java.util.concurrent;
2
3
4 /**
5 * Utility operations for built-in synchronization and {@link Lock} classes.
6 * <p>The <tt>Locks</tt> class defines utility methods that enhance the
7 * use of <tt>synchronized</tt> methods and statements by:
8 * <ul>
9 * <li>allowing for an attempt to acquire a monitor lock only if it is free,
10 * or if it becomes free within a specified time;
11 * <li>allowing an attempt to acquire a monitor lock to be interruptible; and
12 * <li>providing a method to acquire multiple monitor locks only if
13 * they are all available.
14 * </ul>
15 * <p>An additional convenience method is provided to acquire multiple
16 * {@link Lock} instances only if they are all available.
17 * <p>To preserve the block-structured locking that is required for the
18 * built-in monitor locks, each method takes a {@link Runnable} action as
19 * an argument and executes its {@link Runnable#run run} method with the
20 * appropriate locks held.
21 * When the {@link Runnable#run run} method completes all locks
22 * are released.
23 *
24 * <p><b>Note:</b> All methods that take {@link Object} parameters treat
25 * those parameters as {@link Object Objects}, even if they happen to be
26 * {@link Lock} instances. These methods will always acquire the monitor
27 * lock of the given object - they will not perform a {@link Lock#lock}
28 * invocation.
29 *
30 * <p>Except where noted, passing a <tt>null</tt> value for any parameter
31 * will result in a {@link NullPointerException} being thrown.
32 *
33 * <h3>Memory Synchronization</h3>
34 * <p>When a {@link Runnable} object's {@link Runnable#run run} method is
35 * executed it means that the appropriate
36 * lock (or locks) has been acquired, and so the memory synchronization
37 * effects of acquiring that lock will have taken place. Similarly, when
38 * the {@link Runnable} object's {@link Runnable#run run} method completes,
39 * the lock (or locks) is released and the associated memory synchronization
40 * effects will take place. Exactly what those memory synchronization
41 * effects are will depend on the nature of the lock and the type of
42 * acquisition/release - for example, reentrantly acquiring a monitor lock
43 * has no associated memory synchronization effects.
44 * <p>When mutliple locks are involved it may be that some of the locks are
45 * acquired and subsequently released, before an unavailable lock is found.
46 * In that case the memory synchronization effects will be those of the locks
47 * that were actually acquired and actually released.
48 *
49 * @since 1.5
50 * @spec JSR-166
51 * @revised $Date: 2003/01/09 17:56:51 $
52 * @editor $Author: dl $
53 *
54 * @fixme add implementation notes for any performance issues related to
55 * timeouts or interrupts
56 **/
57 public class Locks {
58
59 private Locks() {} // uninstantiable.
60
61 /**
62 * Performs the given action holding the monitor lock of
63 * the given object only if that lock is currently free.
64 *
65 * <p>If the monitor lock of the given object is immediately available
66 * to the current thread then it is acquired.
67 * The action is then executed and finally the monitor lock is released
68 * and the method returns with the value <tt>true</tt>.
69 * <p>If the monitor lock is not available then the method returns
70 * immediately with the value <tt>false</tt>.
71 * <p>If the action completes abruptly due to an {@link Error} or
72 * {@link RuntimeException}, then the method completes abruptly
73 * for the same reason, after the lock has been released.
74 *
75 * @param lock the object whose monitor lock must be acquired
76 * @param action the code to run while holding the monitor lock
77 * @return <tt>true</tt> if the action was executed, and <tt>false</tt>
78 * otherwise.
79 **/
80 public static boolean attempt(Object lock, Runnable action) {
81 return false; // for now;
82 }
83
84 /**
85 * Performs the given action holding the monitor lock of
86 * the given object if it is free within the given waiting time and the
87 * current thread has not been {@link Thread#interrupt interrupted}.
88 *
89 * <p>If the monitor lock of the given object is immediately available
90 * to the current thread then it is acquired.
91 * The action is then executed and finally the monitor lock is released
92 * and the method returns with the value <tt>true</tt>.
93 *
94 * <p>If the monitor lock is not available then
95 * the current thread becomes disabled for thread scheduling
96 * purposes and lies dormant until one of three things happens:
97 * <ul>
98 * <li> The monitor lock is acquired by the current thread; or
99 * <li> Some other thread {@link Thread#interrupt interrupts} the current
100 * thread; or
101 * <li> The specified waiting time elapses
102 * </ul>
103 * <p>If the monitor lock is acquired
104 * the action is executed then the monitor lock is released
105 * and the method returns with the value <tt>true</tt>.
106 *
107 * <p>If the action completes abruptly due to an {@link Error} or
108 * {@link RuntimeException}, then the method completes abruptly
109 * for the same reason, after the lock has been released.
110 *
111 * <p>If the current thread:
112 * <ul>
113 * <li>has its interrupted status set on entry to this method; or
114 * <li>is {@link Thread#interrupt interrupted} while waiting to acquire
115 * the monitor lock,
116 * </ul>
117 * then {@link InterruptedException} is thrown and the current thread's
118 * interrupted status is cleared.
119 *
120 * <p>If the specified waiting time elapses then the value <tt>false</tt>
121 * is returned.
122 * The given waiting time is a best-effort lower bound. If the time is
123 * less than or equal to zero, the method will not wait at all.
124 *
125 * <p><b>Implementation Notes</b>
126 * <p>TO-BE-DONE
127 *
128 *
129 * @param lock the object whose monitor lock must be acquired
130 * @param action the code to run while holding the monitor lock
131 * @param timeout the maximum time to wait for the monitor lock
132 * @param granularity the time unit of the <tt>timeout</tt> argument.
133 * @return <tt>true</tt> if the monitor lock was acquired and the
134 * action executed, and <tt>false</tt>
135 * if the waiting time elapsed before the monitor lock was acquired.
136 *
137 * @throws InterruptedException if the current thread is interrupted
138 * while trying to acquire the monitor lock.
139 *
140 * @see Thread#interrupt
141 *
142 **/
143 public static boolean attempt(Object lock, Runnable action,
144 long timeout, TimeUnit granularity)
145 throws InterruptedException {
146
147 return false; // for now;
148 }
149
150 /**
151 * Performs the given action holding the monitor locks of
152 * the given objects only if those locks are currently free.
153 *
154 * <p>If the monitor locks of each object in the array are immediately
155 * available to the current thread then they are acquired.
156 * The action is then executed and finally the monitor locks are released
157 * and the method returns with the value <tt>true</tt>.
158 * <p>If any of the monitor locks is not available then
159 * all previously acquired monitor locks are released and the method
160 * returns with the value <tt>false</tt>.
161 * <p>If the action completes abruptly due to an {@link Error} or
162 * {@link RuntimeException}, then the method completes abruptly
163 * for the same reason, after all the locks have been released.
164 *
165 * @param locks the objects whose monitor locks must be acquired
166 * @param action the code to run while holding the monitor locks
167 * @return <tt>true</tt> if the action was executed, and <tt>false</tt>
168 * otherwise.
169 *
170 * @throws NullPointerException if an attempt is made to acquire the
171 * monitor lock of a <tt>null</tt> element in the <tt>locks</tt> array.
172 **/
173 public static boolean attempt(Object[] locks, Runnable action) {
174 return false; // for now;
175 }
176
177 /**
178 * Performs the given action holding the given {@link Lock} instances, only
179 * if those {@link Lock} instances are currently free.
180 *
181 * <p>If each of the locks in the array are immediately
182 * available to the current thread then they are acquired.
183 * The action is then executed and finally the locks are
184 * released and the method returns with the value <tt>true</tt>.
185 * <p>If any of the locks are not available then
186 * all previously acquired locks are released and the
187 * method returns immediately with the value <tt>false</tt>.
188 * <p>If the action completes abruptly due to an {@link Error} or
189 * {@link RuntimeException}, then the method completes abruptly
190 * for the same reason, after all the locks have been
191 * released.
192 *
193 * @param locks the {@link Lock} instances that must be acquired
194 * @param action the code to run while holding the given locks
195 * @return <tt>true</tt> if the action was executed, and <tt>false</tt>
196 * otherwise.
197 *
198 * @throws NullPointerException if an attempt is made to acquire the
199 * lock of a <tt>null</tt> element in the <tt>locks</tt> array.
200 **/
201 public static boolean attempt(Lock[] locks, Runnable action) {
202 return false; // for now;
203 }
204
205
206 /**
207 * Returns a {@link Condition} instance for use with the given object.
208 * <p>The returned {@link Condition} instance has analagous behavior
209 * to the use of the monitor methods on the given object. Given
210 * <pre> Condition c = Locks.newConditionFor(o);
211 * </pre>
212 * then:
213 * <ul>
214 * <li><tt>c.await()</tt> is analagous to <tt>o.wait()</tt>
215 * <li><tt>c.signal()</tt> is analagous to <tt>o.notify()</tt>; and
216 * <li><tt>c.signalAll()</tt> is analagous to <tt>o.notifyAll()</tt>
217 * </ul>
218 * in that:
219 * <ul>
220 * <li>If the monitor lock of <tt>o</tt> is not held when any of the
221 * {@link Condition}
222 * {@link Condition#await() waiting} or {@link Condition#signal signalling}
223 * methods are called, then an {@link IllegalMonitorStateException} is
224 * thrown.
225 * <li>When the condition {@link Condition#await() waiting} methods are
226 * called the monitor lock of <tt>o</tt> is released and before they
227 * return the monitor lock is
228 * reacquired and the lock count restored to what it was when the
229 * method was called.
230 * <li>If a thread is {@link Thread#interrupt interrupted} while waiting
231 * then the wait will terminate, an {@link InterruptedException} will be
232 * thrown, and the thread's interrupted status will be cleared.
233 * <li>The order in which waiting threads are signalled is not specified.
234 * <li>The order in which threads returning from await, and threads trying
235 * to acquire the monitor lock, are granted the lock, is not specified.
236 * </ul>
237 * <p>A {@link Condition} instance obtained in this way can be used to
238 * create the
239 * affect of having additional monitor wait-sets for the given object.
240 * For example, suppose we have a bounded buffer which supports methods
241 * to <tt>put</tt> and <tt>take</tt> items in/from the buffer. If a
242 * <tt>take</tt> is attempted on an empty buffer then the thread will block
243 * until an item becomes available; if a <tt>put</tt> is attempted on a
244 * full buffer, then the thread will block until a space becomes available.
245 * We would like to keep waiting <tt>put</tt> threads and <tt>take</tt>
246 * threads in separate wait-sets so that we can use the optimisation of
247 * only notifying a single thread at a time when items, or spaces, become
248 * available in the buffer. This can be achieved using either two
249 * {@link Condition} instances, or one {@link Condition} instance and the
250 * actual
251 * monitor wait-set. For clarity we'll use two {@link Condition} instances.
252 * <pre><code>
253 * class BoundedBuffer {
254 * <b>final Condition notFull = Locks.newConditionFor(this);
255 * final Condition notEmpty = Locks.newConditionFor(this); </b>
256 *
257 * Object[] items = new Object[100];
258 * int putptr, takeptr, count;
259 *
260 * public <b>synchronized</b> void put(Object x)
261 * throws InterruptedException {
262 * while (count == items.length)
263 * <b>notFull.await();</b>
264 * items[putptr] = x;
265 * if (++putptr == items.length) putptr = 0;
266 * ++count;
267 * <b>notEmpty.signal();</b>
268 * }
269 *
270 * public <b>synchronized</b> Object take() throws InterruptedException {
271 * while (count == 0)
272 * <b>notEmpty.await();</b>
273 * Object x = items[takeptr];
274 * if (++takeptr == items.length) takeptr = 0;
275 * --count;
276 * <b>notFull.signal();</b>
277 * return x;
278 * }
279 * }
280 * </code></pre>
281 *
282 * @param lock the object that will be used for its monitor lock and to
283 * which the returned condition should be bound.
284 * @return a {@link Condition} instance bound to the given object
285 **/
286 public static Condition newConditionFor(Object lock) {
287 return null; // for now;
288 }
289
290 }
291
292
293
294