1 |
package java.util.concurrent; |
2 |
|
3 |
/** |
4 |
* A reentrant mutual exclusion lock. |
5 |
* <p><tt>ReentrantLock</tt> defines a stand-alone {@link Lock} class with |
6 |
* the same basic behavior and semantics as the implicit |
7 |
* monitor lock accessed by the use of <tt>synchronized</tt> methods and |
8 |
* statements, but without the forced block-structured locking and unlocking |
9 |
* that occurs with <tt>synchronized</tt> methods and |
10 |
* statements. |
11 |
* In a good implementation the performance characteristics of using a |
12 |
* <tt>ReentrantLock</tt> instance should be about the same as using |
13 |
* monitors directly. |
14 |
* |
15 |
* <p><em>Only</em> use this class when you want normal locking semantics but |
16 |
* need to use the lock in a non-nested fashion. |
17 |
* |
18 |
* <p>The order in which blocked threads are granted the lock is not |
19 |
* specified. |
20 |
* |
21 |
* <p>If you want a non-reentrant mutual exclusion lock then it is a simple |
22 |
* matter to use a reentrant lock in a non-reentrant way by ensuring that |
23 |
* the lock is not held by the current thread prior to locking. |
24 |
* See {@link #getHoldCount} for a way to check this. |
25 |
* |
26 |
* |
27 |
* <p><code>ReentrantLock</code> instances are intended to be used primarily |
28 |
* in before/after constructions such as: |
29 |
* |
30 |
* <pre> |
31 |
* class X { |
32 |
* ReentrantLock lock; |
33 |
* // ... |
34 |
* |
35 |
* public void m() { |
36 |
* lock.lock(); // block until condition holds |
37 |
* try { |
38 |
* // ... method body |
39 |
* } finally { |
40 |
* lock.unlock() |
41 |
* } |
42 |
* } |
43 |
* } |
44 |
* </pre> |
45 |
* |
46 |
* <p>This class supports the interruption of lock acquisition and provides a |
47 |
* {@link #newCondition Condition} implementation that supports the |
48 |
* interruption of thread suspension. |
49 |
* |
50 |
* <p>Except where noted, passing a <tt>null</tt> value for any parameter |
51 |
* will result in a {@link NullPointerException} being thrown. |
52 |
* |
53 |
* <h3>Implentation Notes</h3> |
54 |
* <p> To-BE_DONE |
55 |
* |
56 |
* |
57 |
* @since 1.5 |
58 |
* @spec JSR-166 |
59 |
* @revised $Date: 2003/02/06 06:41:13 $ |
60 |
* @editor $Author: dholmes $ |
61 |
* |
62 |
* @fixme (1) We need a non-nested example to motivate this |
63 |
* @fixme (2) Describe performance aspects of interruptible locking for the RI |
64 |
**/ |
65 |
public class ReentrantLock implements Lock { |
66 |
|
67 |
/** |
68 |
* Creates an instance of <tt>ReentrantLock</tt> |
69 |
*/ |
70 |
public ReentrantLock() {} |
71 |
|
72 |
/** |
73 |
* Acquirea the lock. |
74 |
* <p>Acquires the lock if it is not held be another thread and returns |
75 |
* immediately, setting the lock hold count to one. |
76 |
* <p>If the current thread |
77 |
* already holds the lock then the hold count is incremented by one and |
78 |
* the method returns immediately. |
79 |
* <p>If the lock is held by another thread then the |
80 |
* the current thread thread becomes disabled for thread scheduling |
81 |
* purposes and lies dormant until the lock has been acquired |
82 |
* at which time the lock hold count is set to one. |
83 |
*/ |
84 |
public void lock() {} |
85 |
|
86 |
/** |
87 |
* Acquires the lock unless the current thread is |
88 |
* {@link Thread#interrupt interrupted}. |
89 |
* <p>Acquires the lock if it is not held by another thread and returns |
90 |
* immediately, setting the lock hold count to one. |
91 |
* <p>If the current thread already holds this lock then the hold count |
92 |
* is incremented by one and the method returns immediately. |
93 |
* <p>If the lock is held by another thread then the |
94 |
* the current thread becomes disabled for thread scheduling |
95 |
* purposes and lies dormant until one of two things happens: |
96 |
* <ul> |
97 |
* <li> The lock is acquired by the current thread; or |
98 |
* <li> Some other thread {@link Thread#interrupt interrupts} the current |
99 |
* thread. |
100 |
* </ul> |
101 |
* <p>If the lock is acquired by the current thread then the lock hold |
102 |
* count is set to one. |
103 |
* <p>If the current thread: |
104 |
* <ul> |
105 |
* <li>has its interrupted status set on entry to this method; or |
106 |
* <li>is {@link Thread#interrupt interrupted} while waiting to acquire |
107 |
* the lock, |
108 |
* </ul> |
109 |
* then {@link InterruptedException} is thrown and the current thread's |
110 |
* interrupted status is cleared. As this method is an explicit |
111 |
* interruption point, preference is given to responding to the interrupt |
112 |
* over reentrant acquisition of the lock. |
113 |
* |
114 |
* <h3>Implentation Notes</h3> |
115 |
* <p> To-BE_DONE |
116 |
* |
117 |
* @throws InterruptedException if the current thread is interrupted |
118 |
*/ |
119 |
public void lockInterruptibly() throws InterruptedException { } |
120 |
|
121 |
/** |
122 |
* Acquires the lock only if it is not held by another thread at the time |
123 |
* of invocation. |
124 |
* <p>Acquires the lock if it is not held by another thread and returns |
125 |
* immediately with the value <tt>true</tt>, setting the lock hold count |
126 |
* to one. |
127 |
* <p> If the current thread |
128 |
* already holds this lock then the hold count is incremented by one and |
129 |
* the method returns <tt>true</code>. |
130 |
* <p>If the lock is held by another thread then this method will return |
131 |
* immediately with the value <tt>false</tt>. |
132 |
* |
133 |
* @return <tt>true</tt>if the lock was free and was acquired by the |
134 |
* current thread, or the lock was already held by the current thread; and |
135 |
* <tt>false</tt> otherwise. |
136 |
*/ |
137 |
public boolean tryLock() { |
138 |
return false; |
139 |
} |
140 |
|
141 |
/** |
142 |
* |
143 |
* Acquires the lock if it is not held by another thread within the given |
144 |
* waiting time and the current thread has not been interrupted. |
145 |
* <p>Acquires the lock if it is not held by another thread and returns |
146 |
* immediately with the value <tt>true</tt>, setting the lock hold count |
147 |
* to one. |
148 |
* <p> If the current thread |
149 |
* already holds this lock then the hold count is incremented by one and |
150 |
* the method returns <tt>true</code>. |
151 |
* <p>If the lock is held by another thread then the |
152 |
* the current thread becomes disabled for thread scheduling |
153 |
* purposes and lies dormant until one of three things happens: |
154 |
* <ul> |
155 |
* <li> The lock is acquired by the current thread; or |
156 |
* <li> Some other thread {@link Thread#interrupt interrupts} the current |
157 |
* thread; or |
158 |
* <li> The specified waiting time elapses |
159 |
* </ul> |
160 |
* <p>If the lock is acquired then the value <tt>true</tt> is returned and |
161 |
* the lock hold count is set to one. |
162 |
* <p>If the current thread: |
163 |
* <ul> |
164 |
* <li>has its interrupted status set on entry to this method; or |
165 |
* <li>is {@link Thread#interrupt interrupted} while waiting to acquire |
166 |
* the lock, |
167 |
* </ul> |
168 |
* then {@link InterruptedException} is thrown and the current thread's |
169 |
* interrupted status is cleared. As this method is an explicit |
170 |
* interruption point, preference is given to responding to the interrupt |
171 |
* over reentrant acquisition of the lock. |
172 |
* <p>If the specified waiting time elapses then the value <tt>false</tt> |
173 |
* is returned. |
174 |
* <p>The given waiting time is a best-effort lower bound. If the time is |
175 |
* less than or equal to zero, the method will not wait at all. |
176 |
* |
177 |
* <h3>Implentation Notes</h3> |
178 |
* <p> To-BE_DONE |
179 |
* |
180 |
* @return <tt>true</tt> if the lock was free and was acquired by the |
181 |
* current thread, or the lock was already held by the current thread; and |
182 |
* <tt>false</tt> if the waiting time elapsed before the lock could be |
183 |
* acquired. |
184 |
* |
185 |
* @throws InterruptedException if the current thread is interrupted |
186 |
*/ |
187 |
public boolean tryLock(long timeout, TimeUnit granularity) throws InterruptedException { |
188 |
return false; |
189 |
} |
190 |
|
191 |
/** |
192 |
* Attempts to release this lock. |
193 |
* <p>If the current thread is the holder of this lock then the hold count |
194 |
* is decremented. If the hold count is now zero then the lock is released. |
195 |
* <p>If the current thread is not the holder of this lock then |
196 |
* {@link IllegalMonitorStateException} is thrown. |
197 |
* @throws IllegalMonitorStateExeception if the current thread does not |
198 |
* hold this lock. |
199 |
*/ |
200 |
public void unlock() {} |
201 |
|
202 |
/** |
203 |
* Queries the number of holds on this lock by the current thread. |
204 |
* <p>A thread has a hold on a lock for each lock action that is not |
205 |
* matched by an unlock action. |
206 |
* <p>The hold count information is typically only used for testing and |
207 |
* debugging purposes. For example, if a certain section of code should |
208 |
* not be entered with the lock already held then we can assert that |
209 |
* fact: |
210 |
* <pre> |
211 |
* class X { |
212 |
* ReentrantLock lock = new ReentrantLock(); |
213 |
* // ... |
214 |
* |
215 |
* public void m() { |
216 |
* assert lock.getHoldCount() == 0; |
217 |
* lock.lock(); |
218 |
* try { |
219 |
* // ... method body |
220 |
* } finally { |
221 |
* lock.unlock() |
222 |
* } |
223 |
* } |
224 |
* } |
225 |
* </pre> |
226 |
* |
227 |
* @return the number of holds on this lock by current thread, |
228 |
* or zero if this lock is not held by current thread. |
229 |
**/ |
230 |
public int getHoldCount() { |
231 |
return 0; |
232 |
} |
233 |
|
234 |
/** |
235 |
* Queries if this lock is held by the current thread. |
236 |
* <p>Analogous to the {@link Thread#holdsLock} method for built-in |
237 |
* monitor locks, this method is typically used for debugging and |
238 |
* testing. For example, a method that should only be called while |
239 |
* a lock is held can assert that this is the case: |
240 |
* <pre> |
241 |
* class X { |
242 |
* ReentrantLock lock = new ReentrantLock(); |
243 |
* // ... |
244 |
* |
245 |
* public void m() { |
246 |
* assert lock.isHeldByCurrentThread(); |
247 |
* // ... method body |
248 |
* } |
249 |
* } |
250 |
* </pre> |
251 |
* |
252 |
* @return <tt>true</tt> if current thread holds this lock and |
253 |
* <tt>false</tt> otherwise. |
254 |
**/ |
255 |
public boolean isHeldByCurrentThread() { |
256 |
return false; |
257 |
} |
258 |
|
259 |
/** |
260 |
* Returns a {@link Condition} instance for use with this |
261 |
* {@link Lock} instance. |
262 |
* |
263 |
* <p>The returned {@link Condition} instance has the same behavior and |
264 |
* usage |
265 |
* restrictions with this lock as the {@link Object} monitor methods |
266 |
* ({@link Object#wait() wait}, {@link Object#notify notify}, and |
267 |
* {@link Object#notifyAll notifyAll}) have with the built-in monitor |
268 |
* lock: |
269 |
* <ul> |
270 |
* <li>If this lock is not held when any of the {@link Condition} |
271 |
* {@link Condition#await() waiting} or {@link Condition#signal signalling} |
272 |
* methods are called, then an {@link IllegalMonitorStateException} is |
273 |
* thrown. |
274 |
* <li>When the condition {@link Condition#await() waiting} methods are |
275 |
* called the lock is released and before they return the lock is |
276 |
* reacquired and the lock hold count restored to what it was when the |
277 |
* method was called. |
278 |
* <li>If a thread is {@link Thread#interrupt interrupted} while waiting |
279 |
* then the wait will terminate, an {@link InterruptedException} will be |
280 |
* thrown, and the thread's interrupted status will be cleared. |
281 |
* <li>The order in which waiting threads are signalled is not specified. |
282 |
* <li>The order in which threads returning from a wait, and threads trying |
283 |
* to acquire the lock, are granted the lock, is not specified. |
284 |
* </ul> |
285 |
*/ |
286 |
public Condition newCondition() { |
287 |
return null; |
288 |
} |
289 |
|
290 |
} |
291 |
|
292 |
|
293 |
|
294 |
|