6 |
|
|
7 |
|
package jsr166e; |
8 |
|
import java.util.concurrent.TimeUnit; |
9 |
+ |
import java.util.concurrent.TimeoutException; |
10 |
|
import java.util.concurrent.locks.Lock; |
11 |
|
import java.util.concurrent.locks.ReentrantLock; |
12 |
|
import java.util.concurrent.locks.Condition; |
23 |
|
* the lock is held. When it is even (i.e., ({@code lock.getSequence() |
24 |
|
* & 1L) == 0L}), the lock is released. Method {@link |
25 |
|
* #awaitAvailability} can be used to await availability of the lock, |
26 |
< |
* returning its current sequence number. Sequence numbers are of type |
27 |
< |
* {@code long} to ensure that they will not wrap around until |
28 |
< |
* hundreds of years of use under current processor rates. A |
29 |
< |
* SequenceLock can be created with a specified number of |
30 |
< |
* spins. Attempts to lock or await release retry at least the given |
31 |
< |
* number of times before blocking. If not specified, a default, |
32 |
< |
* possibly platform-specific, value is used. |
26 |
> |
* returning its current sequence number. Sequence numbers (as well as |
27 |
> |
* reentrant hold counts) are of type {@code long} to ensure that they |
28 |
> |
* will not wrap around until hundreds of years of use under current |
29 |
> |
* processor rates. A SequenceLock can be created with a specified |
30 |
> |
* number of spins. Attempts to acquire the lock in method {@link |
31 |
> |
* #lock} will retry at least the given number of times before |
32 |
> |
* blocking. If not specified, a default, possibly platform-specific, |
33 |
> |
* value is used. |
34 |
|
* |
35 |
|
* <p>Except for the lack of support for specified fairness policies, |
36 |
< |
* or {link Condition} objects, a SequenceLock can be used in the same |
37 |
< |
* way as {@link ReentrantLock}, and has a nearly identical |
38 |
< |
* API. SequenceLocks may be preferable in contexts in which multiple |
39 |
< |
* threads invoke read-only methods much more frequently than fully |
40 |
< |
* locked methods. |
41 |
< |
* |
36 |
> |
* or {@link Condition} objects, a SequenceLock can be used in the |
37 |
> |
* same way as {@link ReentrantLock}. It provides similar status and |
38 |
> |
* monitoring methods, such as {@link #isHeldByCurrentThread}. |
39 |
> |
* SequenceLocks may be preferable in contexts in which multiple |
40 |
> |
* threads invoke short read-only methods much more frequently than |
41 |
> |
* fully locked methods. |
42 |
> |
* |
43 |
|
* <p> Methods {@code awaitAvailability} and {@code getSequence} can |
44 |
|
* be used together to define (partially) optimistic read-only methods |
45 |
|
* that are usually more efficient than ReadWriteLocks when they |
46 |
< |
* apply. These read-only methods typically read multiple field |
47 |
< |
* values into local variables when the lock is not held, retrying if |
48 |
< |
* the sequence number changed while doing so. Alternatively, because |
49 |
< |
* {@code awaitAvailability} accommodates reentrancy, a method can |
50 |
< |
* retry a bounded number of times before switching to locking mode. |
51 |
< |
* While conceptually straightforward, expressing these ideas can be |
52 |
< |
* verbose. For example: |
46 |
> |
* apply. These methods should in general be structured as loops that |
47 |
> |
* await lock availability, then read {@code volatile} fields into |
48 |
> |
* local variables (and may further read other values derived from |
49 |
> |
* these, for example the {@code length} of a {@code volatile} array), |
50 |
> |
* and retry if the sequence number changed while doing so. |
51 |
> |
* Alternatively, because {@code awaitAvailability} accommodates |
52 |
> |
* reentrancy, a method can retry a bounded number of times before |
53 |
> |
* switching to locking mode. While conceptually straightforward, |
54 |
> |
* expressing these ideas can be verbose. For example: |
55 |
|
* |
56 |
< |
* <pre> {@code |
56 |
> |
* <pre> {@code |
57 |
|
* class Point { |
58 |
< |
* private float x, y; |
59 |
< |
* private final SequenceLock sl = new SequenceLock(); |
58 |
> |
* private volatile double x, y; |
59 |
> |
* private final SequenceLock sl = new SequenceLock(); |
60 |
|
* |
61 |
< |
* void move(float deltaX, float deltaY) { // an excluively locked method |
62 |
< |
* sl.lock(); |
63 |
< |
* try { |
64 |
< |
* x += deltaX; |
65 |
< |
* y += deltaY; |
66 |
< |
* } finally { |
67 |
< |
* sl.unlock(); |
68 |
< |
* } |
69 |
< |
* } |
61 |
> |
* // an exclusively locked method |
62 |
> |
* void move(double deltaX, double deltaY) { |
63 |
> |
* sl.lock(); |
64 |
> |
* try { |
65 |
> |
* x += deltaX; |
66 |
> |
* y += deltaY; |
67 |
> |
* } finally { |
68 |
> |
* sl.unlock(); |
69 |
> |
* } |
70 |
> |
* } |
71 |
|
* |
72 |
< |
* float distanceFromOriginV1() { // A read-only method |
73 |
< |
* float currentX, currentY; |
74 |
< |
* long seq; |
75 |
< |
* do { |
76 |
< |
* seq = sl.awaitAvailability(); |
77 |
< |
* currentX = x; |
78 |
< |
* currentY = y; |
79 |
< |
* } while (sl.getSequence() != seq); // retry if sequence changed |
80 |
< |
* return (float)Math.sqrt(currentX * currentX + currentY * currentY); |
81 |
< |
* } |
72 |
> |
* // A read-only method |
73 |
> |
* double distanceFromOriginV1() { |
74 |
> |
* double currentX, currentY; |
75 |
> |
* long seq; |
76 |
> |
* do { |
77 |
> |
* seq = sl.awaitAvailability(); |
78 |
> |
* currentX = x; |
79 |
> |
* currentY = y; |
80 |
> |
* } while (sl.getSequence() != seq); // retry if sequence changed |
81 |
> |
* return Math.sqrt(currentX * currentX + currentY * currentY); |
82 |
> |
* } |
83 |
|
* |
84 |
< |
* float distanceFromOriginV2() { // Uses bounded retries before locking |
85 |
< |
* float currentX, currentY; |
86 |
< |
* long seq; |
87 |
< |
* int retries = RETRIES_BEFORE_LOCKING; // for example 8 |
88 |
< |
* try { |
89 |
< |
* do { |
90 |
< |
* if (--retries < 0) |
91 |
< |
* sl.lock(); |
92 |
< |
* seq = sl.awaitAvailability(); |
93 |
< |
* currentX = x; |
94 |
< |
* currentY = y; |
95 |
< |
* } while (sl.getSequence() != seq); |
96 |
< |
* } finally { |
97 |
< |
* if (retries < 0) |
98 |
< |
* sl.unlock(); |
99 |
< |
* } |
100 |
< |
* return (float)Math.sqrt(currentX * currentX + currentY * currentY); |
101 |
< |
* } |
102 |
< |
*}}</pre> |
84 |
> |
* // Uses bounded retries before locking |
85 |
> |
* double distanceFromOriginV2() { |
86 |
> |
* double currentX, currentY; |
87 |
> |
* long seq; |
88 |
> |
* int retries = RETRIES_BEFORE_LOCKING; // for example 8 |
89 |
> |
* try { |
90 |
> |
* do { |
91 |
> |
* if (--retries < 0) |
92 |
> |
* sl.lock(); |
93 |
> |
* seq = sl.awaitAvailability(); |
94 |
> |
* currentX = x; |
95 |
> |
* currentY = y; |
96 |
> |
* } while (sl.getSequence() != seq); |
97 |
> |
* } finally { |
98 |
> |
* if (retries < 0) |
99 |
> |
* sl.unlock(); |
100 |
> |
* } |
101 |
> |
* return Math.sqrt(currentX * currentX + currentY * currentY); |
102 |
> |
* } |
103 |
> |
* }}</pre> |
104 |
|
* |
105 |
|
* @since 1.8 |
106 |
|
* @author Doug Lea |
117 |
|
/** |
118 |
|
* The number of reentrant holds on this lock. Uses a long for |
119 |
|
* compatibility with other AbstractQueuedLongSynchronizer |
120 |
< |
* operations. |
120 |
> |
* operations. Accessed only by lock holder. |
121 |
|
*/ |
122 |
|
long holds; |
123 |
|
|
129 |
|
return (getState() & 1L) != 0L && |
130 |
|
getExclusiveOwnerThread() == Thread.currentThread(); |
131 |
|
} |
132 |
< |
|
133 |
< |
public final boolean tryAcquire(long acquires) { |
132 |
> |
|
133 |
> |
public final boolean tryAcquire(long acquires) { |
134 |
|
Thread current = Thread.currentThread(); |
135 |
|
long c = getState(); |
136 |
|
if ((c & 1L) == 0L) { |
146 |
|
} |
147 |
|
return false; |
148 |
|
} |
149 |
< |
|
149 |
> |
|
150 |
|
public final boolean tryRelease(long releases) { |
151 |
|
if (Thread.currentThread() != getExclusiveOwnerThread()) |
152 |
|
throw new IllegalMonitorStateException(); |
159 |
|
} |
160 |
|
|
161 |
|
public final long tryAcquireShared(long unused) { |
162 |
< |
return ((getState() & 1L) == 0L || |
163 |
< |
getExclusiveOwnerThread() == Thread.currentThread())? |
164 |
< |
1L : -1L; // must return long |
162 |
> |
return (((getState() & 1L) == 0L) ? 1L : |
163 |
> |
(getExclusiveOwnerThread() == Thread.currentThread()) ? 0L: |
164 |
> |
-1L); |
165 |
|
} |
166 |
|
|
167 |
|
public final boolean tryReleaseShared(long unused) { |
168 |
< |
return true; |
168 |
> |
return (getState() & 1L) == 0L; |
169 |
|
} |
170 |
|
|
171 |
< |
public final Condition newCondition() { |
171 |
> |
public final Condition newCondition() { |
172 |
|
throw new UnsupportedOperationException(); |
173 |
|
} |
174 |
|
|
177 |
|
final long getSequence() { |
178 |
|
return getState(); |
179 |
|
} |
180 |
< |
|
180 |
> |
|
181 |
|
final void lock() { |
182 |
|
int k = spins; |
183 |
< |
while (!tryAcquire(1)) { |
183 |
> |
while (!tryAcquire(1L)) { |
184 |
|
if (k == 0) { |
185 |
< |
acquire(1); |
185 |
> |
acquire(1L); |
186 |
|
break; |
187 |
|
} |
188 |
|
--k; |
189 |
|
} |
190 |
|
} |
191 |
< |
|
191 |
> |
|
192 |
|
final long awaitAvailability() { |
193 |
|
long s; |
186 |
– |
int k = spins; |
194 |
|
while (((s = getState()) & 1L) != 0L && |
195 |
|
getExclusiveOwnerThread() != Thread.currentThread()) { |
196 |
< |
if (k > 0) |
197 |
< |
--k; |
191 |
< |
else { |
192 |
< |
acquireShared(1); |
193 |
< |
releaseShared(1); |
194 |
< |
} |
196 |
> |
acquireShared(1L); |
197 |
> |
releaseShared(1L); |
198 |
|
} |
199 |
|
return s; |
200 |
|
} |
201 |
|
|
202 |
+ |
final long tryAwaitAvailability(long nanos) |
203 |
+ |
throws InterruptedException, TimeoutException { |
204 |
+ |
Thread current = Thread.currentThread(); |
205 |
+ |
for (;;) { |
206 |
+ |
long s = getState(); |
207 |
+ |
if ((s & 1L) == 0L || getExclusiveOwnerThread() == current) { |
208 |
+ |
releaseShared(1L); |
209 |
+ |
return s; |
210 |
+ |
} |
211 |
+ |
if (!tryAcquireSharedNanos(1L, nanos)) |
212 |
+ |
throw new TimeoutException(); |
213 |
+ |
// since tryAcquireSharedNanos doesn't return seq |
214 |
+ |
// retry with minimal wait time. |
215 |
+ |
nanos = 1L; |
216 |
+ |
} |
217 |
+ |
} |
218 |
+ |
|
219 |
|
final boolean isLocked() { |
220 |
|
return (getState() & 1L) != 0L; |
221 |
|
} |
225 |
|
} |
226 |
|
|
227 |
|
final long getHoldCount() { |
228 |
< |
return isHeldExclusively()? holds : 0; |
228 |
> |
return isHeldExclusively() ? holds : 0; |
229 |
|
} |
230 |
|
|
231 |
|
private void readObject(ObjectInputStream s) |
238 |
|
|
239 |
|
private final Sync sync; |
240 |
|
|
241 |
< |
/** |
241 |
> |
/** |
242 |
|
* The default spin value for constructor. Future versions of this |
243 |
|
* class might choose platform-specific values. Currently, except |
244 |
< |
* on uniprocessors, it is set to a small value that ovecomes near |
244 |
> |
* on uniprocessors, it is set to a small value that overcomes near |
245 |
|
* misses between releases and acquires. |
246 |
|
*/ |
247 |
< |
static final int DEFAULT_SPINS = |
247 |
> |
static final int DEFAULT_SPINS = |
248 |
|
Runtime.getRuntime().availableProcessors() > 1 ? 64 : 0; |
249 |
|
|
250 |
|
/** |
251 |
|
* Creates an instance of {@code SequenceLock} with the default |
252 |
< |
* number of retry attempts to lock or await release before |
233 |
< |
* blocking. |
252 |
> |
* number of retry attempts to acquire the lock before blocking. |
253 |
|
*/ |
254 |
|
public SequenceLock() { sync = new Sync(DEFAULT_SPINS); } |
255 |
|
|
256 |
|
/** |
257 |
< |
* Creates an instance of {@code SequenceLock} that |
258 |
< |
* will retry attempts to lock or await release |
259 |
< |
* at least the given number times before blocking. |
257 |
> |
* Creates an instance of {@code SequenceLock} that will retry |
258 |
> |
* attempts to acquire the lock at least the given number times |
259 |
> |
* before blocking. |
260 |
|
*/ |
261 |
|
public SequenceLock(int spins) { sync = new Sync(spins); } |
262 |
|
|
263 |
|
/** |
264 |
|
* Returns the current sequence number of this lock. The sequence |
265 |
< |
* number is advanced upon each lock or unlock action. When this |
266 |
< |
* value is odd, the lock is held; when even, it is released. |
265 |
> |
* number is advanced upon each acquire or release action. When |
266 |
> |
* this value is odd, the lock is held; when even, it is released. |
267 |
|
* |
268 |
|
* @return the current sequence number |
269 |
|
*/ |
280 |
|
* @return the current sequence number |
281 |
|
*/ |
282 |
|
public long awaitAvailability() { return sync.awaitAvailability(); } |
283 |
< |
|
283 |
> |
|
284 |
|
/** |
285 |
< |
* Acquires the lock. |
285 |
> |
* Returns the current sequence number if the lock is, or |
286 |
> |
* becomes, available within the specified waiting time. |
287 |
> |
* |
288 |
> |
* <p>If the lock is not available, the current thread becomes |
289 |
> |
* disabled for thread scheduling purposes and lies dormant until |
290 |
> |
* one of three things happens: |
291 |
> |
* |
292 |
> |
* <ul> |
293 |
> |
* |
294 |
> |
* <li>The lock becomes available, in which case the current |
295 |
> |
* sequence number is returned. |
296 |
|
* |
297 |
< |
* <p>Acquires the lock if it is not held by another thread and returns |
298 |
< |
* immediately, setting the lock hold count to one. |
297 |
> |
* <li>Some other thread {@linkplain Thread#interrupt interrupts} |
298 |
> |
* the current thread, in which case this method throws |
299 |
> |
* {@link InterruptedException}. |
300 |
> |
* |
301 |
> |
* <li>The specified waiting time elapses, in which case |
302 |
> |
* this method throws {@link TimeoutException}. |
303 |
|
* |
304 |
< |
* <p>If the current thread already holds the lock then the hold |
272 |
< |
* count is incremented by one and the method returns immediately. |
304 |
> |
* </ul> |
305 |
|
* |
306 |
< |
* <p>If the lock is held by another thread then the |
307 |
< |
* current thread becomes disabled for thread scheduling |
308 |
< |
* purposes and lies dormant until the lock has been acquired, |
309 |
< |
* at which time the lock hold count is set to one. |
306 |
> |
* @param timeout the time to wait for availability |
307 |
> |
* @param unit the time unit of the timeout argument |
308 |
> |
* @return the current sequence number if the lock is available |
309 |
> |
* upon return from this method |
310 |
> |
* @throws InterruptedException if the current thread is interrupted |
311 |
> |
* @throws TimeoutException if the lock was not available within |
312 |
> |
* the specified waiting time |
313 |
> |
* @throws NullPointerException if the time unit is null |
314 |
> |
*/ |
315 |
> |
public long tryAwaitAvailability(long timeout, TimeUnit unit) |
316 |
> |
throws InterruptedException, TimeoutException { |
317 |
> |
return sync.tryAwaitAvailability(unit.toNanos(timeout)); |
318 |
> |
} |
319 |
> |
|
320 |
> |
/** |
321 |
> |
* Acquires the lock. |
322 |
> |
* |
323 |
> |
* <p>If the current thread already holds this lock then the hold count |
324 |
> |
* is incremented by one and the method returns immediately without |
325 |
> |
* incrementing the sequence number. |
326 |
> |
* |
327 |
> |
* <p>If this lock not held by another thread, this method |
328 |
> |
* increments the sequence number (which thus becomes an odd |
329 |
> |
* number), sets the lock hold count to one, and returns |
330 |
> |
* immediately. |
331 |
> |
* |
332 |
> |
* <p>If the lock is held by another thread then the current |
333 |
> |
* thread may retry acquiring this lock, depending on the {@code |
334 |
> |
* spin} count established in constructor. If the lock is still |
335 |
> |
* not acquired, the current thread becomes disabled for thread |
336 |
> |
* scheduling purposes and lies dormant until enabled by |
337 |
> |
* some other thread releasing the lock. |
338 |
|
*/ |
339 |
|
public void lock() { sync.lock(); } |
340 |
|
|
342 |
|
* Acquires the lock unless the current thread is |
343 |
|
* {@linkplain Thread#interrupt interrupted}. |
344 |
|
* |
285 |
– |
* <p>Acquires the lock if it is not held by another thread and returns |
286 |
– |
* immediately, setting the lock hold count to one. |
287 |
– |
* |
345 |
|
* <p>If the current thread already holds this lock then the hold count |
346 |
< |
* is incremented by one and the method returns immediately. |
346 |
> |
* is incremented by one and the method returns immediately without |
347 |
> |
* incrementing the sequence number. |
348 |
|
* |
349 |
< |
* <p>If the lock is held by another thread then the |
350 |
< |
* current thread becomes disabled for thread scheduling |
351 |
< |
* purposes and lies dormant until one of two things happens: |
349 |
> |
* <p>If this lock not held by another thread, this method |
350 |
> |
* increments the sequence number (which thus becomes an odd |
351 |
> |
* number), sets the lock hold count to one, and returns |
352 |
> |
* immediately. |
353 |
> |
* |
354 |
> |
* <p>If the lock is held by another thread then the current |
355 |
> |
* thread may retry acquiring this lock, depending on the {@code |
356 |
> |
* spin} count established in constructor. If the lock is still |
357 |
> |
* not acquired, the current thread becomes disabled for thread |
358 |
> |
* scheduling purposes and lies dormant until one of two things |
359 |
> |
* happens: |
360 |
|
* |
361 |
|
* <ul> |
362 |
|
* |
368 |
|
* </ul> |
369 |
|
* |
370 |
|
* <p>If the lock is acquired by the current thread then the lock hold |
371 |
< |
* count is set to one. |
371 |
> |
* count is set to one and the sequence number is incremented. |
372 |
|
* |
373 |
|
* <p>If the current thread: |
374 |
|
* |
391 |
|
* @throws InterruptedException if the current thread is interrupted |
392 |
|
*/ |
393 |
|
public void lockInterruptibly() throws InterruptedException { |
394 |
< |
sync.acquireInterruptibly(1); |
394 |
> |
sync.acquireInterruptibly(1L); |
395 |
|
} |
396 |
|
|
397 |
|
/** |
398 |
|
* Acquires the lock only if it is not held by another thread at the time |
399 |
|
* of invocation. |
400 |
|
* |
401 |
< |
* <p>Acquires the lock if it is not held by another thread and |
402 |
< |
* returns immediately with the value {@code true}, setting the |
403 |
< |
* lock hold count to one. |
401 |
> |
* <p>If the current thread already holds this lock then the hold |
402 |
> |
* count is incremented by one and the method returns {@code true} |
403 |
> |
* without incrementing the sequence number. |
404 |
> |
* |
405 |
> |
* <p>If this lock not held by another thread, this method |
406 |
> |
* increments the sequence number (which thus becomes an odd |
407 |
> |
* number), sets the lock hold count to one, and returns {@code |
408 |
> |
* true}. |
409 |
|
* |
410 |
< |
* <p> If the current thread already holds this lock then the hold |
411 |
< |
* count is incremented by one and the method returns {@code true}. |
341 |
< |
* |
342 |
< |
* <p>If the lock is held by another thread then this method will return |
343 |
< |
* immediately with the value {@code false}. |
410 |
> |
* <p>If the lock is held by another thread then this method |
411 |
> |
* returns {@code false}. |
412 |
|
* |
413 |
|
* @return {@code true} if the lock was free and was acquired by the |
414 |
|
* current thread, or the lock was already held by the current |
415 |
|
* thread; and {@code false} otherwise |
416 |
|
*/ |
417 |
< |
public boolean tryLock() { return sync.tryAcquire(1); } |
417 |
> |
public boolean tryLock() { return sync.tryAcquire(1L); } |
418 |
|
|
419 |
|
/** |
420 |
|
* Acquires the lock if it is not held by another thread within the given |
421 |
|
* waiting time and the current thread has not been |
422 |
|
* {@linkplain Thread#interrupt interrupted}. |
423 |
|
* |
424 |
< |
* <p>Acquires the lock if it is not held by another thread and returns |
425 |
< |
* immediately with the value {@code true}, setting the lock hold count |
426 |
< |
* to one. If this lock has been set to use a fair ordering policy then |
427 |
< |
* an available lock <em>will not</em> be acquired if any other threads |
428 |
< |
* are waiting for the lock. This is in contrast to the {@link #tryLock()} |
429 |
< |
* method. If you want a timed {@code tryLock} that does permit barging on |
430 |
< |
* a fair lock then combine the timed and un-timed forms together: |
431 |
< |
* |
432 |
< |
* <pre> {@code |
433 |
< |
* if (lock.tryLock() || |
434 |
< |
* lock.tryLock(timeout, unit)) { |
435 |
< |
* ... |
436 |
< |
* }}</pre> |
437 |
< |
* |
438 |
< |
* <p>If the current thread |
371 |
< |
* already holds this lock then the hold count is incremented by one and |
372 |
< |
* the method returns {@code true}. |
373 |
< |
* |
374 |
< |
* <p>If the lock is held by another thread then the |
375 |
< |
* current thread becomes disabled for thread scheduling |
376 |
< |
* purposes and lies dormant until one of three things happens: |
424 |
> |
* <p>If the current thread already holds this lock then the hold count |
425 |
> |
* is incremented by one and the method returns immediately without |
426 |
> |
* incrementing the sequence number. |
427 |
> |
* |
428 |
> |
* <p>If this lock not held by another thread, this method |
429 |
> |
* increments the sequence number (which thus becomes an odd |
430 |
> |
* number), sets the lock hold count to one, and returns |
431 |
> |
* immediately. |
432 |
> |
* |
433 |
> |
* <p>If the lock is held by another thread then the current |
434 |
> |
* thread may retry acquiring this lock, depending on the {@code |
435 |
> |
* spin} count established in constructor. If the lock is still |
436 |
> |
* not acquired, the current thread becomes disabled for thread |
437 |
> |
* scheduling purposes and lies dormant until one of three things |
438 |
> |
* happens: |
439 |
|
* |
440 |
|
* <ul> |
441 |
|
* |
485 |
|
*/ |
486 |
|
public boolean tryLock(long timeout, TimeUnit unit) |
487 |
|
throws InterruptedException { |
488 |
< |
return sync.tryAcquireNanos(1, unit.toNanos(timeout)); |
488 |
> |
return sync.tryAcquireNanos(1L, unit.toNanos(timeout)); |
489 |
|
} |
490 |
|
|
491 |
|
/** |
492 |
|
* Attempts to release this lock. |
493 |
|
* |
494 |
< |
* <p>If the current thread is the holder of this lock then the hold |
495 |
< |
* count is decremented. If the hold count is now zero then the lock |
496 |
< |
* is released. If the current thread is not the holder of this |
497 |
< |
* lock then {@link IllegalMonitorStateException} is thrown. |
494 |
> |
* <p>If the current thread is the holder of this lock then the |
495 |
> |
* hold count is decremented. If the hold count is now zero then |
496 |
> |
* the sequence number is incremented (thus becoming an even |
497 |
> |
* number) and the lock is released. If the current thread is not |
498 |
> |
* the holder of this lock then {@link |
499 |
> |
* IllegalMonitorStateException} is thrown. |
500 |
|
* |
501 |
|
* @throws IllegalMonitorStateException if the current thread does not |
502 |
|
* hold this lock |
509 |
|
* |
510 |
|
* @throws UnsupportedOperationException |
511 |
|
*/ |
512 |
< |
public Condition newCondition() { |
512 |
> |
public Condition newCondition() { |
513 |
|
throw new UnsupportedOperationException(); |
514 |
|
} |
515 |
|
|
520 |
|
* matched by an unlock action. |
521 |
|
* |
522 |
|
* <p>The hold count information is typically only used for testing and |
523 |
< |
* debugging purposes. |
523 |
> |
* debugging purposes. |
524 |
|
* |
525 |
|
* @return the number of holds on this lock by the current thread, |
526 |
|
* or zero if this lock is not held by the current thread |
634 |
|
} |
635 |
|
|
636 |
|
} |
637 |
< |
|
637 |
> |
|