KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > java > util > concurrent > locks > Lock


1 /*
2  * @(#)Lock.java 1.4 03/12/19
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package java.util.concurrent.locks;
9 import java.util.concurrent.TimeUnit JavaDoc;
10
11 /**
12  * <tt>Lock</tt> implementations provide more extensive locking
13  * operations than can be obtained using <tt>synchronized</tt> methods
14  * and statements. They allow more flexible structuring, may have
15  * quite different properties, and may support multiple associated
16  * {@link Condition} objects.
17  *
18  * <p>A lock is a tool for controlling access to a shared resource by
19  * multiple threads. Commonly, a lock provides exclusive access to a
20  * shared resource: only one thread at a time can acquire the lock and
21  * all access to the shared resource requires that the lock be
22  * acquired first. However, some locks may allow concurrent access to
23  * a shared resource, such as the read lock of a {@link
24  * ReadWriteLock}.
25  *
26  * <p>The use of <tt>synchronized</tt> methods or statements provides
27  * access to the implicit monitor lock associated with every object, but
28  * forces all lock acquisition and release to occur in a block-structured way:
29  * when multiple locks are acquired they must be released in the opposite
30  * order, and all locks must be released in the same lexical scope in which
31  * they were acquired.
32  *
33  * <p>While the scoping mechanism for <tt>synchronized</tt> methods
34  * and statements makes it much easier to program with monitor locks,
35  * and helps avoid many common programming errors involving locks,
36  * there are occasions where you need to work with locks in a more
37  * flexible way. For example, some algorithms for traversing
38  * concurrently accessed data structures require the use of
39  * &quot;hand-over-hand&quot; or &quot;chain locking&quot;: you
40  * acquire the lock of node A, then node B, then release A and acquire
41  * C, then release B and acquire D and so on. Implementations of the
42  * <tt>Lock</tt> interface enable the use of such techniques by
43  * allowing a lock to be acquired and released in different scopes,
44  * and allowing multiple locks to be acquired and released in any
45  * order.
46  *
47  * <p>With this increased flexibility comes additional
48  * responsibility. The absence of block-structured locking removes the
49  * automatic release of locks that occurs with <tt>synchronized</tt>
50  * methods and statements. In most cases, the following idiom
51  * should be used:
52  *
53  * <pre><tt> Lock l = ...;
54  * l.lock();
55  * try {
56  * // access the resource protected by this lock
57  * } finally {
58  * l.unlock();
59  * }
60  * </tt></pre>
61  *
62  * When locking and unlocking occur in different scopes, care must be
63  * taken to ensure that all code that is executed while the lock is
64  * held is protected by try-finally or try-catch to ensure that the
65  * lock is released when necessary.
66  *
67  * <p><tt>Lock</tt> implementations provide additional functionality
68  * over the use of <tt>synchronized</tt> methods and statements by
69  * providing a non-blocking attempt to acquire a lock ({@link
70  * #tryLock()}), an attempt to acquire the lock that can be
71  * interrupted ({@link #lockInterruptibly}, and an attempt to acquire
72  * the lock that can timeout ({@link #tryLock(long, TimeUnit)}).
73  *
74  * <p>A <tt>Lock</tt> class can also provide behavior and semantics
75  * that is quite different from that of the implicit monitor lock,
76  * such as guaranteed ordering, non-reentrant usage, or deadlock
77  * detection. If an implementation provides such specialized semantics
78  * then the implementation must document those semantics.
79  *
80  * <p>Note that <tt>Lock</tt> instances are just normal objects and can
81  * themselves be used as the target in a <tt>synchronized</tt> statement.
82  * Acquiring the
83  * monitor lock of a <tt>Lock</tt> instance has no specified relationship
84  * with invoking any of the {@link #lock} methods of that instance.
85  * It is recommended that to avoid confusion you never use <tt>Lock</tt>
86  * instances in this way, except within their own implementation.
87  *
88  * <p>Except where noted, passing a <tt>null</tt> value for any
89  * parameter will result in a {@link NullPointerException} being
90  * thrown.
91  *
92  * <h3>Memory Synchronization</h3>
93  * <p>All <tt>Lock</tt> implementations <em>must</em> enforce the same
94  * memory synchronization semantics as provided by the built-in monitor lock:
95  * <ul>
96  * <li>A successful lock operation acts like a successful
97  * <tt>monitorEnter</tt> action
98  * <li>A successful <tt>unlock</tt> operation acts like a successful
99  * <tt>monitorExit</tt> action
100  * </ul>
101  *
102  * Unsuccessful locking and unlocking operations, and reentrant
103  * locking/unlocking operations, do not require any memory
104  * synchronization effects.
105  *
106  * <h3>Implementation Considerations</h3>
107  *
108  * <p> The three forms of lock acquisition (interruptible,
109  * non-interruptible, and timed) may differ in their performance
110  * characteristics, ordering guarantees, or other implementation
111  * qualities. Further, the ability to interrupt the <em>ongoing</em>
112  * acquisition of a lock may not be available in a given <tt>Lock</tt>
113  * class. Consequently, an implementation is not required to define
114  * exactly the same guarantees or semantics for all three forms of
115  * lock acquisition, nor is it required to support interruption of an
116  * ongoing lock acquisition. An implementation is required to clearly
117  * document the semantics and guarantees provided by each of the
118  * locking methods. It must also obey the interruption semantics as
119  * defined in this interface, to the extent that interruption of lock
120  * acquisition is supported: which is either totally, or only on
121  * method entry.
122  *
123  * <p>As interruption generally implies cancellation, and checks for
124  * interruption are often infrequent, an implementation can favor responding
125  * to an interrupt over normal method return. This is true even if it can be
126  * shown that the interrupt occurred after another action may have unblocked
127  * the thread. An implementation should document this behavior.
128  *
129  *
130  * @see ReentrantLock
131  * @see Condition
132  * @see ReadWriteLock
133  *
134  * @since 1.5
135  * @author Doug Lea
136  *
137  **/

138 public interface Lock {
139
140     /**
141      * Acquires the lock.
142      * <p>If the lock is not available then
143      * the current thread becomes disabled for thread scheduling
144      * purposes and lies dormant until the lock has been acquired.
145      * <p><b>Implementation Considerations</b>
146      * <p>A <tt>Lock</tt> implementation may be able to detect
147      * erroneous use of the lock, such as an invocation that would cause
148      * deadlock, and may throw an (unchecked) exception in such circumstances.
149      * The circumstances and the exception type must be documented by that
150      * <tt>Lock</tt> implementation.
151      *
152      **/

153     void lock();
154
155     /**
156      * Acquires the lock unless the current thread is
157      * {@link Thread#interrupt interrupted}.
158      * <p>Acquires the lock if it is available and returns immediately.
159      * <p>If the lock is not available then
160      * the current thread becomes disabled for thread scheduling
161      * purposes and lies dormant until one of two things happens:
162      * <ul>
163      * <li>The lock is acquired by the current thread; or
164      * <li>Some other thread {@link Thread#interrupt interrupts} the current
165      * thread, and interruption of lock acquisition is supported.
166      * </ul>
167      * <p>If the current thread:
168      * <ul>
169      * <li>has its interrupted status set on entry to this method; or
170      * <li>is {@link Thread#interrupt interrupted} while acquiring
171      * the lock, and interruption of lock acquisition is supported,
172      * </ul>
173      * then {@link InterruptedException} is thrown and the current thread's
174      * interrupted status is cleared.
175      *
176      * <p><b>Implementation Considerations</b>
177      *
178      * <p>The ability to interrupt a lock acquisition in some
179      * implementations may not be possible, and if possible may be an
180      * expensive operation. The programmer should be aware that this
181      * may be the case. An implementation should document when this is
182      * the case.
183      *
184      * <p>An implementation can favor responding to an interrupt over
185      * normal method return.
186      *
187      * <p>A <tt>Lock</tt> implementation may be able to detect
188      * erroneous use of the lock, such as an invocation that would
189      * cause deadlock, and may throw an (unchecked) exception in such
190      * circumstances. The circumstances and the exception type must
191      * be documented by that <tt>Lock</tt> implementation.
192      *
193      * @throws InterruptedException if the current thread is interrupted
194      * while acquiring the lock (and interruption of lock acquisition is
195      * supported).
196      *
197      * @see Thread#interrupt
198      *
199      **/

200     void lockInterruptibly() throws InterruptedException JavaDoc;
201
202
203     /**
204      * Acquires the lock only if it is free at the time of invocation.
205      * <p>Acquires the lock if it is available and returns immediately
206      * with the value <tt>true</tt>.
207      * If the lock is not available then this method will return
208      * immediately with the value <tt>false</tt>.
209      * <p>A typical usage idiom for this method would be:
210      * <pre>
211      * Lock lock = ...;
212      * if (lock.tryLock()) {
213      * try {
214      * // manipulate protected state
215      * } finally {
216      * lock.unlock();
217      * }
218      * } else {
219      * // perform alternative actions
220      * }
221      * </pre>
222      * This usage ensures that the lock is unlocked if it was acquired, and
223      * doesn't try to unlock if the lock was not acquired.
224      *
225      * @return <tt>true</tt> if the lock was acquired and <tt>false</tt>
226      * otherwise.
227      **/

228     boolean tryLock();
229
230     /**
231      * Acquires the lock if it is free within the given waiting time and the
232      * current thread has not been {@link Thread#interrupt interrupted}.
233      *
234      * <p>If the lock is available this method returns immediately
235      * with the value <tt>true</tt>.
236      * If the lock is not available then
237      * the current thread becomes disabled for thread scheduling
238      * purposes and lies dormant until one of three things happens:
239      * <ul>
240      * <li>The lock is acquired by the current thread; or
241      * <li>Some other thread {@link Thread#interrupt interrupts} the current
242      * thread, and interruption of lock acquisition is supported; or
243      * <li>The specified waiting time elapses
244      * </ul>
245      * <p>If the lock is acquired then the value <tt>true</tt> is returned.
246      * <p>If the current thread:
247      * <ul>
248      * <li>has its interrupted status set on entry to this method; or
249      * <li>is {@link Thread#interrupt interrupted} while acquiring
250      * the lock, and interruption of lock acquisition is supported,
251      * </ul>
252      * then {@link InterruptedException} is thrown and the current thread's
253      * interrupted status is cleared.
254      * <p>If the specified waiting time elapses then the value <tt>false</tt>
255      * is returned.
256      * If the time is
257      * less than or equal to zero, the method will not wait at all.
258      *
259      * <p><b>Implementation Considerations</b>
260      * <p>The ability to interrupt a lock acquisition in some implementations
261      * may not be possible, and if possible may
262      * be an expensive operation.
263      * The programmer should be aware that this may be the case. An
264      * implementation should document when this is the case.
265      * <p>An implementation can favor responding to an interrupt over normal
266      * method return, or reporting a timeout.
267      * <p>A <tt>Lock</tt> implementation may be able to detect
268      * erroneous use of the lock, such as an invocation that would cause
269      * deadlock, and may throw an (unchecked) exception in such circumstances.
270      * The circumstances and the exception type must be documented by that
271      * <tt>Lock</tt> implementation.
272      *
273      * @param time the maximum time to wait for the lock
274      * @param unit the time unit of the <tt>time</tt> argument.
275      * @return <tt>true</tt> if the lock was acquired and <tt>false</tt>
276      * if the waiting time elapsed before the lock was acquired.
277      *
278      * @throws InterruptedException if the current thread is interrupted
279      * while acquiring the lock (and interruption of lock acquisition is
280      * supported).
281      *
282      * @see Thread#interrupt
283      *
284      **/

285     boolean tryLock(long time, TimeUnit JavaDoc unit) throws InterruptedException JavaDoc;
286
287     /**
288      * Releases the lock.
289      * <p><b>Implementation Considerations</b>
290      * <p>A <tt>Lock</tt> implementation will usually impose
291      * restrictions on which thread can release a lock (typically only the
292      * holder of the lock can release it) and may throw
293      * an (unchecked) exception if the restriction is violated.
294      * Any restrictions and the exception
295      * type must be documented by that <tt>Lock</tt> implementation.
296      **/

297     void unlock();
298
299     /**
300      * Returns a new {@link Condition} instance that is bound to this
301      * <tt>Lock</tt> instance.
302      * <p>Before waiting on the condition the lock must be held by the
303      * current thread.
304      * A call to {@link Condition#await()} will atomically release the lock
305      * before waiting and re-acquire the lock before the wait returns.
306      * <p><b>Implementation Considerations</b>
307      * <p>The exact operation of the {@link Condition} instance depends on the
308      * <tt>Lock</tt> implementation and must be documented by that
309      * implementation.
310      *
311      * @return A new {@link Condition} instance for this <tt>Lock</tt>
312      * instance.
313      * @throws UnsupportedOperationException if this <tt>Lock</tt>
314      * implementation does not support conditions.
315      **/

316     Condition JavaDoc newCondition();
317
318 }
319
320
321
322
323
324
325
326
327
328
329
330
331
Popular Tags