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 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

# User Rev Content
1 tim 1.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