001: /*
002: * Written by Doug Lea with assistance from members of JCP JSR-166
003: * Expert Group and released to the public domain, as explained at
004: * http://creativecommons.org/licenses/publicdomain
005: */
006:
007: package org.drools.util.concurrent.locks;
008:
009: //import edu.emory.mathcs.backport.java.util.concurrent.locks.*; // for javadoc (till 6280605 is fixed)
010: //import edu.emory.mathcs.backport.java.util.concurrent.TimeUnit;
011:
012: /**
013: * <tt>Lock</tt> implementations provide more extensive locking
014: * operations than can be obtained using <tt>synchronized</tt> methods
015: * and statements. They allow more flexible structuring, may have
016: * quite different properties, and may support multiple associated
017: * {@link Condition} objects.
018: *
019: * <p>A lock is a tool for controlling access to a shared resource by
020: * multiple threads. Commonly, a lock provides exclusive access to a
021: * shared resource: only one thread at a time can acquire the lock and
022: * all access to the shared resource requires that the lock be
023: * acquired first. However, some locks may allow concurrent access to
024: * a shared resource, such as the read lock of a {@link
025: * ReadWriteLock}.
026: *
027: * <p>The use of <tt>synchronized</tt> methods or statements provides
028: * access to the implicit monitor lock associated with every object, but
029: * forces all lock acquisition and release to occur in a block-structured way:
030: * when multiple locks are acquired they must be released in the opposite
031: * order, and all locks must be released in the same lexical scope in which
032: * they were acquired.
033: *
034: * <p>While the scoping mechanism for <tt>synchronized</tt> methods
035: * and statements makes it much easier to program with monitor locks,
036: * and helps avoid many common programming errors involving locks,
037: * there are occasions where you need to work with locks in a more
038: * flexible way. For example, some algorithms for traversing
039: * concurrently accessed data structures require the use of
040: * "hand-over-hand" or "chain locking": you
041: * acquire the lock of node A, then node B, then release A and acquire
042: * C, then release B and acquire D and so on. Implementations of the
043: * <tt>Lock</tt> interface enable the use of such techniques by
044: * allowing a lock to be acquired and released in different scopes,
045: * and allowing multiple locks to be acquired and released in any
046: * order.
047: *
048: * <p>With this increased flexibility comes additional
049: * responsibility. The absence of block-structured locking removes the
050: * automatic release of locks that occurs with <tt>synchronized</tt>
051: * methods and statements. In most cases, the following idiom
052: * should be used:
053: *
054: * <pre><tt> Lock l = ...;
055: * l.lock();
056: * try {
057: * // access the resource protected by this lock
058: * } finally {
059: * l.unlock();
060: * }
061: * </tt></pre>
062: *
063: * When locking and unlocking occur in different scopes, care must be
064: * taken to ensure that all code that is executed while the lock is
065: * held is protected by try-finally or try-catch to ensure that the
066: * lock is released when necessary.
067: *
068: * <p><tt>Lock</tt> implementations provide additional functionality
069: * over the use of <tt>synchronized</tt> methods and statements by
070: * providing a non-blocking attempt to acquire a lock ({@link
071: * #tryLock()}), an attempt to acquire the lock that can be
072: * interrupted ({@link #lockInterruptibly}, and an attempt to acquire
073: * the lock that can timeout ({@link #tryLock(long, TimeUnit)}).
074: *
075: * <p>A <tt>Lock</tt> class can also provide behavior and semantics
076: * that is quite different from that of the implicit monitor lock,
077: * such as guaranteed ordering, non-reentrant usage, or deadlock
078: * detection. If an implementation provides such specialized semantics
079: * then the implementation must document those semantics.
080: *
081: * <p>Note that <tt>Lock</tt> instances are just normal objects and can
082: * themselves be used as the target in a <tt>synchronized</tt> statement.
083: * Acquiring the
084: * monitor lock of a <tt>Lock</tt> instance has no specified relationship
085: * with invoking any of the {@link #lock} methods of that instance.
086: * It is recommended that to avoid confusion you never use <tt>Lock</tt>
087: * instances in this way, except within their own implementation.
088: *
089: * <p>Except where noted, passing a <tt>null</tt> value for any
090: * parameter will result in a {@link NullPointerException} being
091: * thrown.
092: *
093: * <h3>Memory Synchronization</h3>
094: * <p>All <tt>Lock</tt> implementations <em>must</em> enforce the same
095: * memory synchronization semantics as provided by the built-in monitor
096: * lock, as described in <a href="http://java.sun.com/docs/books/jls/">
097: * The Java Language Specification, Third Edition (17.4 Memory Model)</a>:
098: * <ul>
099: * <li>A successful <tt>lock</tt> operation has the same memory
100: * synchronization effects as a successful <em>Lock</em> action.
101: * <li>A successful <tt>unlock</tt> operation has the same
102: * memory synchronization effects as a successful <em>Unlock</em> action.
103: * </ul>
104: *
105: * Unsuccessful locking and unlocking operations, and reentrant
106: * locking/unlocking operations, do not require any memory
107: * synchronization effects.
108: *
109: * <h3>Implementation Considerations</h3>
110: *
111: * <p> The three forms of lock acquisition (interruptible,
112: * non-interruptible, and timed) may differ in their performance
113: * characteristics, ordering guarantees, or other implementation
114: * qualities. Further, the ability to interrupt the <em>ongoing</em>
115: * acquisition of a lock may not be available in a given <tt>Lock</tt>
116: * class. Consequently, an implementation is not required to define
117: * exactly the same guarantees or semantics for all three forms of
118: * lock acquisition, nor is it required to support interruption of an
119: * ongoing lock acquisition. An implementation is required to clearly
120: * document the semantics and guarantees provided by each of the
121: * locking methods. It must also obey the interruption semantics as
122: * defined in this interface, to the extent that interruption of lock
123: * acquisition is supported: which is either totally, or only on
124: * method entry.
125: *
126: * <p>As interruption generally implies cancellation, and checks for
127: * interruption are often infrequent, an implementation can favor responding
128: * to an interrupt over normal method return. This is true even if it can be
129: * shown that the interrupt occurred after another action may have unblocked
130: * the thread. An implementation should document this behavior.
131: *
132: *
133: * @see ReentrantLock
134: * @see Condition
135: * @see ReadWriteLock
136: *
137: * @since 1.5
138: * @author Doug Lea
139: *
140: */
141: public interface Lock {
142:
143: /**
144: * Acquires the lock.
145: * <p>If the lock is not available then
146: * the current thread becomes disabled for thread scheduling
147: * purposes and lies dormant until the lock has been acquired.
148: * <p><b>Implementation Considerations</b>
149: * <p>A <tt>Lock</tt> implementation may be able to detect
150: * erroneous use of the lock, such as an invocation that would cause
151: * deadlock, and may throw an (unchecked) exception in such circumstances.
152: * The circumstances and the exception type must be documented by that
153: * <tt>Lock</tt> implementation.
154: */
155: void lock();
156:
157: /**
158: * Acquires the lock unless the current thread is
159: * {@link Thread#interrupt interrupted}.
160: * <p>Acquires the lock if it is available and returns immediately.
161: * <p>If the lock is not available then
162: * the current thread becomes disabled for thread scheduling
163: * purposes and lies dormant until one of two things happens:
164: * <ul>
165: * <li>The lock is acquired by the current thread; or
166: * <li>Some other thread {@link Thread#interrupt interrupts} the current
167: * thread, and interruption of lock acquisition is supported.
168: * </ul>
169: * <p>If the current thread:
170: * <ul>
171: * <li>has its interrupted status set on entry to this method; or
172: * <li>is {@link Thread#interrupt interrupted} while acquiring
173: * the lock, and interruption of lock acquisition is supported,
174: * </ul>
175: * then {@link InterruptedException} is thrown and the current thread's
176: * interrupted status is cleared.
177: *
178: * <p><b>Implementation Considerations</b>
179: *
180: * <p>The ability to interrupt a lock acquisition in some
181: * implementations may not be possible, and if possible may be an
182: * expensive operation. The programmer should be aware that this
183: * may be the case. An implementation should document when this is
184: * the case.
185: *
186: * <p>An implementation can favor responding to an interrupt over
187: * normal method return.
188: *
189: * <p>A <tt>Lock</tt> implementation may be able to detect
190: * erroneous use of the lock, such as an invocation that would
191: * cause deadlock, and may throw an (unchecked) exception in such
192: * circumstances. The circumstances and the exception type must
193: * be documented by that <tt>Lock</tt> implementation.
194: *
195: * @throws InterruptedException if the current thread is interrupted
196: * while acquiring the lock (and interruption of lock acquisition is
197: * supported).
198: *
199: * @see Thread#interrupt
200: */
201: void lockInterruptibly() throws InterruptedException;
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: * Releases the lock.
232: * <p><b>Implementation Considerations</b>
233: * <p>A <tt>Lock</tt> implementation will usually impose
234: * restrictions on which thread can release a lock (typically only the
235: * holder of the lock can release it) and may throw
236: * an (unchecked) exception if the restriction is violated.
237: * Any restrictions and the exception
238: * type must be documented by that <tt>Lock</tt> implementation.
239: */
240: void unlock();
241:
242: }
|