Print this page
Split |
Close |
Expand all |
Collapse all |
--- old/src/share/classes/java/util/concurrent/locks/ReentrantLock.java
+++ new/src/share/classes/java/util/concurrent/locks/ReentrantLock.java
1 1 /*
2 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3 3 *
4 4 * This code is free software; you can redistribute it and/or modify it
5 5 * under the terms of the GNU General Public License version 2 only, as
6 6 * published by the Free Software Foundation. Oracle designates this
7 7 * particular file as subject to the "Classpath" exception as provided
8 8 * by Oracle in the LICENSE file that accompanied this code.
9 9 *
10 10 * This code is distributed in the hope that it will be useful, but WITHOUT
11 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 13 * version 2 for more details (a copy is included in the LICENSE file that
14 14 * accompanied this code).
15 15 *
16 16 * You should have received a copy of the GNU General Public License version
17 17 * 2 along with this work; if not, write to the Free Software Foundation,
18 18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 19 *
20 20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 21 * or visit www.oracle.com if you need additional information or have any
22 22 * questions.
23 23 */
24 24
25 25 /*
26 26 * This file is available under and governed by the GNU General Public
27 27 * License version 2 only, as published by the Free Software Foundation.
28 28 * However, the following notice accompanied the original version of this
29 29 * file:
30 30 *
31 31 * Written by Doug Lea with assistance from members of JCP JSR-166
32 32 * Expert Group and released to the public domain, as explained at
33 33 * http://creativecommons.org/licenses/publicdomain
34 34 */
35 35
36 36 package java.util.concurrent.locks;
37 37 import java.util.*;
38 38 import java.util.concurrent.*;
39 39 import java.util.concurrent.atomic.*;
40 40
41 41 /**
42 42 * A reentrant mutual exclusion {@link Lock} with the same basic
43 43 * behavior and semantics as the implicit monitor lock accessed using
44 44 * {@code synchronized} methods and statements, but with extended
45 45 * capabilities.
46 46 *
47 47 * <p>A {@code ReentrantLock} is <em>owned</em> by the thread last
48 48 * successfully locking, but not yet unlocking it. A thread invoking
49 49 * {@code lock} will return, successfully acquiring the lock, when
50 50 * the lock is not owned by another thread. The method will return
51 51 * immediately if the current thread already owns the lock. This can
52 52 * be checked using methods {@link #isHeldByCurrentThread}, and {@link
53 53 * #getHoldCount}.
54 54 *
55 55 * <p>The constructor for this class accepts an optional
56 56 * <em>fairness</em> parameter. When set {@code true}, under
57 57 * contention, locks favor granting access to the longest-waiting
58 58 * thread. Otherwise this lock does not guarantee any particular
59 59 * access order. Programs using fair locks accessed by many threads
60 60 * may display lower overall throughput (i.e., are slower; often much
61 61 * slower) than those using the default setting, but have smaller
62 62 * variances in times to obtain locks and guarantee lack of
63 63 * starvation. Note however, that fairness of locks does not guarantee
64 64 * fairness of thread scheduling. Thus, one of many threads using a
65 65 * fair lock may obtain it multiple times in succession while other
66 66 * active threads are not progressing and not currently holding the
67 67 * lock.
68 68 * Also note that the untimed {@link #tryLock() tryLock} method does not
69 69 * honor the fairness setting. It will succeed if the lock
70 70 * is available even if other threads are waiting.
71 71 *
72 72 * <p>It is recommended practice to <em>always</em> immediately
73 73 * follow a call to {@code lock} with a {@code try} block, most
74 74 * typically in a before/after construction such as:
75 75 *
76 76 * <pre>
77 77 * class X {
78 78 * private final ReentrantLock lock = new ReentrantLock();
79 79 * // ...
80 80 *
81 81 * public void m() {
82 82 * lock.lock(); // block until condition holds
83 83 * try {
84 84 * // ... method body
85 85 * } finally {
86 86 * lock.unlock()
87 87 * }
88 88 * }
89 89 * }
90 90 * </pre>
91 91 *
92 92 * <p>In addition to implementing the {@link Lock} interface, this
93 93 * class defines methods {@code isLocked} and
94 94 * {@code getLockQueueLength}, as well as some associated
95 95 * {@code protected} access methods that may be useful for
96 96 * instrumentation and monitoring.
97 97 *
98 98 * <p>Serialization of this class behaves in the same way as built-in
99 99 * locks: a deserialized lock is in the unlocked state, regardless of
100 100 * its state when serialized.
101 101 *
102 102 * <p>This lock supports a maximum of 2147483647 recursive locks by
103 103 * the same thread. Attempts to exceed this limit result in
104 104 * {@link Error} throws from locking methods.
105 105 *
106 106 * @since 1.5
107 107 * @author Doug Lea
108 108 */
↓ open down ↓ |
108 lines elided |
↑ open up ↑ |
109 109 public class ReentrantLock implements Lock, java.io.Serializable {
110 110 private static final long serialVersionUID = 7373984872572414699L;
111 111 /** Synchronizer providing all implementation mechanics */
112 112 private final Sync sync;
113 113
114 114 /**
115 115 * Base of synchronization control for this lock. Subclassed
116 116 * into fair and nonfair versions below. Uses AQS state to
117 117 * represent the number of holds on the lock.
118 118 */
119 - static abstract class Sync extends AbstractQueuedSynchronizer {
119 + abstract static class Sync extends AbstractQueuedSynchronizer {
120 120 private static final long serialVersionUID = -5179523762034025860L;
121 121
122 122 /**
123 123 * Performs {@link Lock#lock}. The main reason for subclassing
124 124 * is to allow fast path for nonfair version.
125 125 */
126 126 abstract void lock();
127 127
128 128 /**
129 129 * Performs non-fair tryLock. tryAcquire is
130 130 * implemented in subclasses, but both need nonfair
131 131 * try for trylock method.
132 132 */
133 133 final boolean nonfairTryAcquire(int acquires) {
134 134 final Thread current = Thread.currentThread();
135 135 int c = getState();
136 136 if (c == 0) {
137 137 if (compareAndSetState(0, acquires)) {
138 138 setExclusiveOwnerThread(current);
139 139 return true;
140 140 }
141 141 }
142 142 else if (current == getExclusiveOwnerThread()) {
143 143 int nextc = c + acquires;
144 144 if (nextc < 0) // overflow
145 145 throw new Error("Maximum lock count exceeded");
146 146 setState(nextc);
147 147 return true;
148 148 }
149 149 return false;
150 150 }
151 151
152 152 protected final boolean tryRelease(int releases) {
153 153 int c = getState() - releases;
154 154 if (Thread.currentThread() != getExclusiveOwnerThread())
155 155 throw new IllegalMonitorStateException();
156 156 boolean free = false;
157 157 if (c == 0) {
158 158 free = true;
159 159 setExclusiveOwnerThread(null);
160 160 }
161 161 setState(c);
162 162 return free;
163 163 }
164 164
165 165 protected final boolean isHeldExclusively() {
166 166 // While we must in general read state before owner,
167 167 // we don't need to do so to check if current thread is owner
168 168 return getExclusiveOwnerThread() == Thread.currentThread();
169 169 }
170 170
171 171 final ConditionObject newCondition() {
172 172 return new ConditionObject();
173 173 }
174 174
175 175 // Methods relayed from outer class
176 176
177 177 final Thread getOwner() {
178 178 return getState() == 0 ? null : getExclusiveOwnerThread();
179 179 }
180 180
181 181 final int getHoldCount() {
182 182 return isHeldExclusively() ? getState() : 0;
183 183 }
184 184
185 185 final boolean isLocked() {
186 186 return getState() != 0;
187 187 }
188 188
189 189 /**
190 190 * Reconstitutes this lock instance from a stream.
191 191 * @param s the stream
192 192 */
↓ open down ↓ |
63 lines elided |
↑ open up ↑ |
193 193 private void readObject(java.io.ObjectInputStream s)
194 194 throws java.io.IOException, ClassNotFoundException {
195 195 s.defaultReadObject();
196 196 setState(0); // reset to unlocked state
197 197 }
198 198 }
199 199
200 200 /**
201 201 * Sync object for non-fair locks
202 202 */
203 - final static class NonfairSync extends Sync {
203 + static final class NonfairSync extends Sync {
204 204 private static final long serialVersionUID = 7316153563782823691L;
205 205
206 206 /**
207 207 * Performs lock. Try immediate barge, backing up to normal
208 208 * acquire on failure.
209 209 */
210 210 final void lock() {
211 211 if (compareAndSetState(0, 1))
212 212 setExclusiveOwnerThread(Thread.currentThread());
213 213 else
214 214 acquire(1);
↓ open down ↓ |
1 lines elided |
↑ open up ↑ |
215 215 }
216 216
217 217 protected final boolean tryAcquire(int acquires) {
218 218 return nonfairTryAcquire(acquires);
219 219 }
220 220 }
221 221
222 222 /**
223 223 * Sync object for fair locks
224 224 */
225 - final static class FairSync extends Sync {
225 + static final class FairSync extends Sync {
226 226 private static final long serialVersionUID = -3000897897090466540L;
227 227
228 228 final void lock() {
229 229 acquire(1);
230 230 }
231 231
232 232 /**
233 233 * Fair version of tryAcquire. Don't grant access unless
234 234 * recursive call or no waiters or is first.
235 235 */
236 236 protected final boolean tryAcquire(int acquires) {
237 237 final Thread current = Thread.currentThread();
238 238 int c = getState();
239 239 if (c == 0) {
240 240 if (!hasQueuedPredecessors() &&
241 241 compareAndSetState(0, acquires)) {
242 242 setExclusiveOwnerThread(current);
243 243 return true;
244 244 }
245 245 }
246 246 else if (current == getExclusiveOwnerThread()) {
247 247 int nextc = c + acquires;
248 248 if (nextc < 0)
249 249 throw new Error("Maximum lock count exceeded");
250 250 setState(nextc);
251 251 return true;
252 252 }
253 253 return false;
254 254 }
255 255 }
256 256
257 257 /**
258 258 * Creates an instance of {@code ReentrantLock}.
259 259 * This is equivalent to using {@code ReentrantLock(false)}.
260 260 */
261 261 public ReentrantLock() {
↓ open down ↓ |
26 lines elided |
↑ open up ↑ |
262 262 sync = new NonfairSync();
263 263 }
264 264
265 265 /**
266 266 * Creates an instance of {@code ReentrantLock} with the
267 267 * given fairness policy.
268 268 *
269 269 * @param fair {@code true} if this lock should use a fair ordering policy
270 270 */
271 271 public ReentrantLock(boolean fair) {
272 - sync = (fair)? new FairSync() : new NonfairSync();
272 + sync = fair ? new FairSync() : new NonfairSync();
273 273 }
274 274
275 275 /**
276 276 * Acquires the lock.
277 277 *
278 278 * <p>Acquires the lock if it is not held by another thread and returns
279 279 * immediately, setting the lock hold count to one.
280 280 *
281 281 * <p>If the current thread already holds the lock then the hold
282 282 * count is incremented by one and the method returns immediately.
283 283 *
284 284 * <p>If the lock is held by another thread then the
285 285 * current thread becomes disabled for thread scheduling
286 286 * purposes and lies dormant until the lock has been acquired,
287 287 * at which time the lock hold count is set to one.
288 288 */
289 289 public void lock() {
290 290 sync.lock();
291 291 }
292 292
293 293 /**
294 294 * Acquires the lock unless the current thread is
295 295 * {@linkplain Thread#interrupt interrupted}.
296 296 *
297 297 * <p>Acquires the lock if it is not held by another thread and returns
298 298 * immediately, setting the lock hold count to one.
299 299 *
300 300 * <p>If the current thread already holds this lock then the hold count
301 301 * is incremented by one and the method returns immediately.
302 302 *
303 303 * <p>If the lock is held by another thread then the
304 304 * current thread becomes disabled for thread scheduling
305 305 * purposes and lies dormant until one of two things happens:
306 306 *
307 307 * <ul>
308 308 *
309 309 * <li>The lock is acquired by the current thread; or
310 310 *
311 311 * <li>Some other thread {@linkplain Thread#interrupt interrupts} the
312 312 * current thread.
313 313 *
314 314 * </ul>
315 315 *
316 316 * <p>If the lock is acquired by the current thread then the lock hold
317 317 * count is set to one.
318 318 *
319 319 * <p>If the current thread:
320 320 *
321 321 * <ul>
322 322 *
323 323 * <li>has its interrupted status set on entry to this method; or
324 324 *
325 325 * <li>is {@linkplain Thread#interrupt interrupted} while acquiring
326 326 * the lock,
327 327 *
328 328 * </ul>
329 329 *
330 330 * then {@link InterruptedException} is thrown and the current thread's
331 331 * interrupted status is cleared.
332 332 *
333 333 * <p>In this implementation, as this method is an explicit
334 334 * interruption point, preference is given to responding to the
335 335 * interrupt over normal or reentrant acquisition of the lock.
336 336 *
337 337 * @throws InterruptedException if the current thread is interrupted
338 338 */
339 339 public void lockInterruptibly() throws InterruptedException {
340 340 sync.acquireInterruptibly(1);
341 341 }
342 342
343 343 /**
344 344 * Acquires the lock only if it is not held by another thread at the time
345 345 * of invocation.
346 346 *
347 347 * <p>Acquires the lock if it is not held by another thread and
348 348 * returns immediately with the value {@code true}, setting the
349 349 * lock hold count to one. Even when this lock has been set to use a
350 350 * fair ordering policy, a call to {@code tryLock()} <em>will</em>
351 351 * immediately acquire the lock if it is available, whether or not
352 352 * other threads are currently waiting for the lock.
353 353 * This "barging" behavior can be useful in certain
354 354 * circumstances, even though it breaks fairness. If you want to honor
355 355 * the fairness setting for this lock, then use
356 356 * {@link #tryLock(long, TimeUnit) tryLock(0, TimeUnit.SECONDS) }
357 357 * which is almost equivalent (it also detects interruption).
358 358 *
359 359 * <p> If the current thread already holds this lock then the hold
360 360 * count is incremented by one and the method returns {@code true}.
361 361 *
362 362 * <p>If the lock is held by another thread then this method will return
363 363 * immediately with the value {@code false}.
364 364 *
365 365 * @return {@code true} if the lock was free and was acquired by the
366 366 * current thread, or the lock was already held by the current
367 367 * thread; and {@code false} otherwise
368 368 */
369 369 public boolean tryLock() {
370 370 return sync.nonfairTryAcquire(1);
371 371 }
372 372
373 373 /**
374 374 * Acquires the lock if it is not held by another thread within the given
375 375 * waiting time and the current thread has not been
376 376 * {@linkplain Thread#interrupt interrupted}.
377 377 *
378 378 * <p>Acquires the lock if it is not held by another thread and returns
379 379 * immediately with the value {@code true}, setting the lock hold count
380 380 * to one. If this lock has been set to use a fair ordering policy then
381 381 * an available lock <em>will not</em> be acquired if any other threads
382 382 * are waiting for the lock. This is in contrast to the {@link #tryLock()}
383 383 * method. If you want a timed {@code tryLock} that does permit barging on
384 384 * a fair lock then combine the timed and un-timed forms together:
385 385 *
386 386 * <pre>if (lock.tryLock() || lock.tryLock(timeout, unit) ) { ... }
387 387 * </pre>
388 388 *
389 389 * <p>If the current thread
390 390 * already holds this lock then the hold count is incremented by one and
391 391 * the method returns {@code true}.
392 392 *
393 393 * <p>If the lock is held by another thread then the
394 394 * current thread becomes disabled for thread scheduling
395 395 * purposes and lies dormant until one of three things happens:
396 396 *
397 397 * <ul>
398 398 *
399 399 * <li>The lock is acquired by the current thread; or
400 400 *
401 401 * <li>Some other thread {@linkplain Thread#interrupt interrupts}
402 402 * the current thread; or
403 403 *
404 404 * <li>The specified waiting time elapses
405 405 *
406 406 * </ul>
407 407 *
408 408 * <p>If the lock is acquired then the value {@code true} is returned and
409 409 * the lock hold count is set to one.
410 410 *
411 411 * <p>If the current thread:
412 412 *
413 413 * <ul>
414 414 *
415 415 * <li>has its interrupted status set on entry to this method; or
416 416 *
417 417 * <li>is {@linkplain Thread#interrupt interrupted} while
418 418 * acquiring the lock,
419 419 *
420 420 * </ul>
421 421 * then {@link InterruptedException} is thrown and the current thread's
422 422 * interrupted status is cleared.
423 423 *
424 424 * <p>If the specified waiting time elapses then the value {@code false}
425 425 * is returned. If the time is less than or equal to zero, the method
426 426 * will not wait at all.
427 427 *
428 428 * <p>In this implementation, as this method is an explicit
429 429 * interruption point, preference is given to responding to the
430 430 * interrupt over normal or reentrant acquisition of the lock, and
431 431 * over reporting the elapse of the waiting time.
432 432 *
↓ open down ↓ |
150 lines elided |
↑ open up ↑ |
433 433 * @param timeout the time to wait for the lock
434 434 * @param unit the time unit of the timeout argument
435 435 * @return {@code true} if the lock was free and was acquired by the
436 436 * current thread, or the lock was already held by the current
437 437 * thread; and {@code false} if the waiting time elapsed before
438 438 * the lock could be acquired
439 439 * @throws InterruptedException if the current thread is interrupted
440 440 * @throws NullPointerException if the time unit is null
441 441 *
442 442 */
443 - public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException {
443 + public boolean tryLock(long timeout, TimeUnit unit)
444 + throws InterruptedException {
444 445 return sync.tryAcquireNanos(1, unit.toNanos(timeout));
445 446 }
446 447
447 448 /**
448 449 * Attempts to release this lock.
449 450 *
450 451 * <p>If the current thread is the holder of this lock then the hold
451 452 * count is decremented. If the hold count is now zero then the lock
452 453 * is released. If the current thread is not the holder of this
453 454 * lock then {@link IllegalMonitorStateException} is thrown.
454 455 *
455 456 * @throws IllegalMonitorStateException if the current thread does not
456 457 * hold this lock
457 458 */
458 459 public void unlock() {
459 460 sync.release(1);
460 461 }
461 462
462 463 /**
463 464 * Returns a {@link Condition} instance for use with this
464 465 * {@link Lock} instance.
465 466 *
466 467 * <p>The returned {@link Condition} instance supports the same
467 468 * usages as do the {@link Object} monitor methods ({@link
468 469 * Object#wait() wait}, {@link Object#notify notify}, and {@link
469 470 * Object#notifyAll notifyAll}) when used with the built-in
470 471 * monitor lock.
471 472 *
472 473 * <ul>
473 474 *
474 475 * <li>If this lock is not held when any of the {@link Condition}
475 476 * {@linkplain Condition#await() waiting} or {@linkplain
476 477 * Condition#signal signalling} methods are called, then an {@link
477 478 * IllegalMonitorStateException} is thrown.
478 479 *
479 480 * <li>When the condition {@linkplain Condition#await() waiting}
480 481 * methods are called the lock is released and, before they
481 482 * return, the lock is reacquired and the lock hold count restored
482 483 * to what it was when the method was called.
483 484 *
484 485 * <li>If a thread is {@linkplain Thread#interrupt interrupted}
485 486 * while waiting then the wait will terminate, an {@link
486 487 * InterruptedException} will be thrown, and the thread's
487 488 * interrupted status will be cleared.
488 489 *
489 490 * <li> Waiting threads are signalled in FIFO order.
490 491 *
491 492 * <li>The ordering of lock reacquisition for threads returning
492 493 * from waiting methods is the same as for threads initially
493 494 * acquiring the lock, which is in the default case not specified,
494 495 * but for <em>fair</em> locks favors those threads that have been
495 496 * waiting the longest.
496 497 *
497 498 * </ul>
498 499 *
499 500 * @return the Condition object
500 501 */
501 502 public Condition newCondition() {
502 503 return sync.newCondition();
503 504 }
504 505
505 506 /**
506 507 * Queries the number of holds on this lock by the current thread.
507 508 *
508 509 * <p>A thread has a hold on a lock for each lock action that is not
509 510 * matched by an unlock action.
510 511 *
511 512 * <p>The hold count information is typically only used for testing and
512 513 * debugging purposes. For example, if a certain section of code should
513 514 * not be entered with the lock already held then we can assert that
514 515 * fact:
515 516 *
516 517 * <pre>
517 518 * class X {
518 519 * ReentrantLock lock = new ReentrantLock();
519 520 * // ...
520 521 * public void m() {
521 522 * assert lock.getHoldCount() == 0;
522 523 * lock.lock();
523 524 * try {
524 525 * // ... method body
525 526 * } finally {
526 527 * lock.unlock();
527 528 * }
528 529 * }
529 530 * }
530 531 * </pre>
531 532 *
532 533 * @return the number of holds on this lock by the current thread,
533 534 * or zero if this lock is not held by the current thread
534 535 */
535 536 public int getHoldCount() {
536 537 return sync.getHoldCount();
537 538 }
538 539
539 540 /**
540 541 * Queries if this lock is held by the current thread.
541 542 *
542 543 * <p>Analogous to the {@link Thread#holdsLock} method for built-in
543 544 * monitor locks, this method is typically used for debugging and
544 545 * testing. For example, a method that should only be called while
545 546 * a lock is held can assert that this is the case:
546 547 *
547 548 * <pre>
548 549 * class X {
549 550 * ReentrantLock lock = new ReentrantLock();
550 551 * // ...
551 552 *
552 553 * public void m() {
553 554 * assert lock.isHeldByCurrentThread();
554 555 * // ... method body
555 556 * }
556 557 * }
557 558 * </pre>
558 559 *
559 560 * <p>It can also be used to ensure that a reentrant lock is used
560 561 * in a non-reentrant manner, for example:
561 562 *
562 563 * <pre>
563 564 * class X {
564 565 * ReentrantLock lock = new ReentrantLock();
565 566 * // ...
566 567 *
567 568 * public void m() {
568 569 * assert !lock.isHeldByCurrentThread();
569 570 * lock.lock();
570 571 * try {
571 572 * // ... method body
572 573 * } finally {
573 574 * lock.unlock();
574 575 * }
575 576 * }
576 577 * }
577 578 * </pre>
578 579 *
579 580 * @return {@code true} if current thread holds this lock and
580 581 * {@code false} otherwise
581 582 */
582 583 public boolean isHeldByCurrentThread() {
583 584 return sync.isHeldExclusively();
584 585 }
585 586
586 587 /**
587 588 * Queries if this lock is held by any thread. This method is
588 589 * designed for use in monitoring of the system state,
589 590 * not for synchronization control.
590 591 *
591 592 * @return {@code true} if any thread holds this lock and
592 593 * {@code false} otherwise
593 594 */
594 595 public boolean isLocked() {
595 596 return sync.isLocked();
596 597 }
597 598
598 599 /**
599 600 * Returns {@code true} if this lock has fairness set true.
600 601 *
601 602 * @return {@code true} if this lock has fairness set true
602 603 */
603 604 public final boolean isFair() {
604 605 return sync instanceof FairSync;
605 606 }
606 607
607 608 /**
608 609 * Returns the thread that currently owns this lock, or
609 610 * {@code null} if not owned. When this method is called by a
610 611 * thread that is not the owner, the return value reflects a
611 612 * best-effort approximation of current lock status. For example,
612 613 * the owner may be momentarily {@code null} even if there are
613 614 * threads trying to acquire the lock but have not yet done so.
614 615 * This method is designed to facilitate construction of
615 616 * subclasses that provide more extensive lock monitoring
616 617 * facilities.
617 618 *
618 619 * @return the owner, or {@code null} if not owned
619 620 */
620 621 protected Thread getOwner() {
621 622 return sync.getOwner();
622 623 }
623 624
624 625 /**
625 626 * Queries whether any threads are waiting to acquire this lock. Note that
626 627 * because cancellations may occur at any time, a {@code true}
627 628 * return does not guarantee that any other thread will ever
628 629 * acquire this lock. This method is designed primarily for use in
629 630 * monitoring of the system state.
630 631 *
631 632 * @return {@code true} if there may be other threads waiting to
632 633 * acquire the lock
633 634 */
634 635 public final boolean hasQueuedThreads() {
635 636 return sync.hasQueuedThreads();
636 637 }
637 638
638 639
639 640 /**
640 641 * Queries whether the given thread is waiting to acquire this
641 642 * lock. Note that because cancellations may occur at any time, a
642 643 * {@code true} return does not guarantee that this thread
643 644 * will ever acquire this lock. This method is designed primarily for use
644 645 * in monitoring of the system state.
645 646 *
646 647 * @param thread the thread
647 648 * @return {@code true} if the given thread is queued waiting for this lock
648 649 * @throws NullPointerException if the thread is null
649 650 */
650 651 public final boolean hasQueuedThread(Thread thread) {
651 652 return sync.isQueued(thread);
652 653 }
653 654
654 655
655 656 /**
656 657 * Returns an estimate of the number of threads waiting to
657 658 * acquire this lock. The value is only an estimate because the number of
658 659 * threads may change dynamically while this method traverses
659 660 * internal data structures. This method is designed for use in
660 661 * monitoring of the system state, not for synchronization
661 662 * control.
662 663 *
663 664 * @return the estimated number of threads waiting for this lock
664 665 */
665 666 public final int getQueueLength() {
666 667 return sync.getQueueLength();
667 668 }
668 669
669 670 /**
670 671 * Returns a collection containing threads that may be waiting to
671 672 * acquire this lock. Because the actual set of threads may change
672 673 * dynamically while constructing this result, the returned
673 674 * collection is only a best-effort estimate. The elements of the
674 675 * returned collection are in no particular order. This method is
675 676 * designed to facilitate construction of subclasses that provide
676 677 * more extensive monitoring facilities.
677 678 *
678 679 * @return the collection of threads
679 680 */
680 681 protected Collection<Thread> getQueuedThreads() {
681 682 return sync.getQueuedThreads();
682 683 }
683 684
684 685 /**
685 686 * Queries whether any threads are waiting on the given condition
686 687 * associated with this lock. Note that because timeouts and
687 688 * interrupts may occur at any time, a {@code true} return does
688 689 * not guarantee that a future {@code signal} will awaken any
689 690 * threads. This method is designed primarily for use in
690 691 * monitoring of the system state.
691 692 *
692 693 * @param condition the condition
693 694 * @return {@code true} if there are any waiting threads
694 695 * @throws IllegalMonitorStateException if this lock is not held
695 696 * @throws IllegalArgumentException if the given condition is
696 697 * not associated with this lock
697 698 * @throws NullPointerException if the condition is null
698 699 */
699 700 public boolean hasWaiters(Condition condition) {
700 701 if (condition == null)
701 702 throw new NullPointerException();
702 703 if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
703 704 throw new IllegalArgumentException("not owner");
704 705 return sync.hasWaiters((AbstractQueuedSynchronizer.ConditionObject)condition);
705 706 }
706 707
707 708 /**
708 709 * Returns an estimate of the number of threads waiting on the
709 710 * given condition associated with this lock. Note that because
710 711 * timeouts and interrupts may occur at any time, the estimate
711 712 * serves only as an upper bound on the actual number of waiters.
712 713 * This method is designed for use in monitoring of the system
713 714 * state, not for synchronization control.
714 715 *
715 716 * @param condition the condition
716 717 * @return the estimated number of waiting threads
717 718 * @throws IllegalMonitorStateException if this lock is not held
718 719 * @throws IllegalArgumentException if the given condition is
719 720 * not associated with this lock
720 721 * @throws NullPointerException if the condition is null
721 722 */
722 723 public int getWaitQueueLength(Condition condition) {
723 724 if (condition == null)
724 725 throw new NullPointerException();
725 726 if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
726 727 throw new IllegalArgumentException("not owner");
727 728 return sync.getWaitQueueLength((AbstractQueuedSynchronizer.ConditionObject)condition);
728 729 }
729 730
730 731 /**
731 732 * Returns a collection containing those threads that may be
732 733 * waiting on the given condition associated with this lock.
733 734 * Because the actual set of threads may change dynamically while
734 735 * constructing this result, the returned collection is only a
735 736 * best-effort estimate. The elements of the returned collection
736 737 * are in no particular order. This method is designed to
737 738 * facilitate construction of subclasses that provide more
738 739 * extensive condition monitoring facilities.
739 740 *
740 741 * @param condition the condition
741 742 * @return the collection of threads
742 743 * @throws IllegalMonitorStateException if this lock is not held
743 744 * @throws IllegalArgumentException if the given condition is
744 745 * not associated with this lock
745 746 * @throws NullPointerException if the condition is null
746 747 */
747 748 protected Collection<Thread> getWaitingThreads(Condition condition) {
748 749 if (condition == null)
749 750 throw new NullPointerException();
750 751 if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
751 752 throw new IllegalArgumentException("not owner");
752 753 return sync.getWaitingThreads((AbstractQueuedSynchronizer.ConditionObject)condition);
753 754 }
754 755
755 756 /**
756 757 * Returns a string identifying this lock, as well as its lock state.
757 758 * The state, in brackets, includes either the String {@code "Unlocked"}
758 759 * or the String {@code "Locked by"} followed by the
759 760 * {@linkplain Thread#getName name} of the owning thread.
760 761 *
761 762 * @return a string identifying this lock, as well as its lock state
762 763 */
763 764 public String toString() {
764 765 Thread o = sync.getOwner();
765 766 return super.toString() + ((o == null) ?
766 767 "[Unlocked]" :
767 768 "[Locked by thread " + o.getName() + "]");
768 769 }
769 770 }
↓ open down ↓ |
316 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX