1 /* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * 4 * This code is free software; you can redistribute it and/or modify it 5 * under the terms of the GNU General Public License version 2 only, as 6 * published by the Free Software Foundation. 7 * 8 * This code is distributed in the hope that it will be useful, but WITHOUT 9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 11 * version 2 for more details (a copy is included in the LICENSE file that 12 * accompanied this code). 13 * 14 * You should have received a copy of the GNU General Public License version 15 * 2 along with this work; if not, write to the Free Software Foundation, 16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 17 * 18 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 19 * or visit www.oracle.com if you need additional information or have any 20 * questions. 21 */ 22 23 /* 24 * This file is available under and governed by the GNU General Public 25 * License version 2 only, as published by the Free Software Foundation. 26 * However, the following notice accompanied the original version of this 27 * file: 28 * 29 * Written by Doug Lea with assistance from members of JCP JSR-166 30 * Expert Group and released to the public domain, as explained at 31 * http://creativecommons.org/publicdomain/zero/1.0/ 32 * Other contributors include Andrew Wright, Jeffrey Hayes, 33 * Pat Fisher, Mike Judd. 34 */ 35 36 import static java.util.concurrent.TimeUnit.MILLISECONDS; 37 import static java.util.concurrent.TimeUnit.NANOSECONDS; 38 39 import java.util.ArrayList; 40 import java.util.Arrays; 41 import java.util.Collection; 42 import java.util.HashSet; 43 import java.util.concurrent.ThreadLocalRandom; 44 import java.util.concurrent.locks.AbstractQueuedSynchronizer; 45 import java.util.concurrent.locks.AbstractQueuedSynchronizer.ConditionObject; 46 47 import junit.framework.Test; 48 import junit.framework.TestSuite; 49 50 @SuppressWarnings("WaitNotInLoop") // we implement spurious-wakeup freedom 51 public class AbstractQueuedSynchronizerTest extends JSR166TestCase { 52 public static void main(String[] args) { 53 main(suite(), args); 54 } 55 public static Test suite() { 56 return new TestSuite(AbstractQueuedSynchronizerTest.class); 57 } 58 59 /** 60 * A simple mutex class, adapted from the class javadoc. Exclusive 61 * acquire tests exercise this as a sample user extension. Other 62 * methods/features of AbstractQueuedSynchronizer are tested via 63 * other test classes, including those for ReentrantLock, 64 * ReentrantReadWriteLock, and Semaphore. 65 * 66 * Unlike the javadoc sample, we don't track owner thread via 67 * AbstractOwnableSynchronizer methods. 68 */ 69 static class Mutex extends AbstractQueuedSynchronizer { 70 /** An eccentric value for locked synchronizer state. */ 71 static final int LOCKED = (1 << 31) | (1 << 15); 72 73 static final int UNLOCKED = 0; 74 75 /** Owner thread is untracked, so this is really just isLocked(). */ 76 @Override public boolean isHeldExclusively() { 77 int state = getState(); 78 assertTrue(state == UNLOCKED || state == LOCKED); 79 return state == LOCKED; 80 } 81 82 @Override protected boolean tryAcquire(int acquires) { 83 assertEquals(LOCKED, acquires); 84 return compareAndSetState(UNLOCKED, LOCKED); 85 } 86 87 @Override protected boolean tryRelease(int releases) { 88 if (getState() != LOCKED) throw new IllegalMonitorStateException(); 89 assertEquals(LOCKED, releases); 90 setState(UNLOCKED); 91 return true; 92 } 93 94 public boolean tryAcquireNanos(long nanos) throws InterruptedException { 95 return tryAcquireNanos(LOCKED, nanos); 96 } 97 98 public boolean tryAcquire() { 99 return tryAcquire(LOCKED); 100 } 101 102 public boolean tryRelease() { 103 return tryRelease(LOCKED); 104 } 105 106 public void acquire() { 107 acquire(LOCKED); 108 } 109 110 public void acquireInterruptibly() throws InterruptedException { 111 acquireInterruptibly(LOCKED); 112 } 113 114 public void release() { 115 release(LOCKED); 116 } 117 118 /** Faux-Implements Lock.newCondition(). */ 119 public ConditionObject newCondition() { 120 return new ConditionObject(); 121 } 122 } 123 124 /** 125 * A minimal latch class, to test shared mode. 126 */ 127 static class BooleanLatch extends AbstractQueuedSynchronizer { 128 public boolean isSignalled() { return getState() != 0; } 129 130 public int tryAcquireShared(int ignore) { 131 return isSignalled() ? 1 : -1; 132 } 133 134 public boolean tryReleaseShared(int ignore) { 135 setState(1); 136 return true; 137 } 138 } 139 140 /** 141 * A runnable calling acquireInterruptibly that does not expect to 142 * be interrupted. 143 */ 144 class InterruptibleSyncRunnable extends CheckedRunnable { 145 final Mutex sync; 146 InterruptibleSyncRunnable(Mutex sync) { this.sync = sync; } 147 public void realRun() throws InterruptedException { 148 sync.acquireInterruptibly(); 149 } 150 } 151 152 /** 153 * A runnable calling acquireInterruptibly that expects to be 154 * interrupted. 155 */ 156 class InterruptedSyncRunnable extends CheckedInterruptedRunnable { 157 final Mutex sync; 158 InterruptedSyncRunnable(Mutex sync) { this.sync = sync; } 159 public void realRun() throws InterruptedException { 160 sync.acquireInterruptibly(); 161 } 162 } 163 164 /** A constant to clarify calls to checking methods below. */ 165 static final Thread[] NO_THREADS = new Thread[0]; 166 167 /** 168 * Spin-waits until sync.isQueued(t) becomes true. 169 */ 170 void waitForQueuedThread(AbstractQueuedSynchronizer sync, Thread t) { 171 long startTime = System.nanoTime(); 172 while (!sync.isQueued(t)) { 173 if (millisElapsedSince(startTime) > LONG_DELAY_MS) 174 throw new AssertionError("timed out"); 175 Thread.yield(); 176 } 177 assertTrue(t.isAlive()); 178 } 179 180 /** 181 * Checks that sync has exactly the given queued threads. 182 */ 183 void assertHasQueuedThreads(AbstractQueuedSynchronizer sync, 184 Thread... expected) { 185 Collection<Thread> actual = sync.getQueuedThreads(); 186 assertEquals(expected.length > 0, sync.hasQueuedThreads()); 187 assertEquals(expected.length, sync.getQueueLength()); 188 assertEquals(expected.length, actual.size()); 189 assertEquals(expected.length == 0, actual.isEmpty()); 190 assertEquals(new HashSet<Thread>(actual), 191 new HashSet<Thread>(Arrays.asList(expected))); 192 } 193 194 /** 195 * Checks that sync has exactly the given (exclusive) queued threads. 196 */ 197 void assertHasExclusiveQueuedThreads(AbstractQueuedSynchronizer sync, 198 Thread... expected) { 199 assertHasQueuedThreads(sync, expected); 200 assertEquals(new HashSet<Thread>(sync.getExclusiveQueuedThreads()), 201 new HashSet<Thread>(sync.getQueuedThreads())); 202 assertEquals(0, sync.getSharedQueuedThreads().size()); 203 assertTrue(sync.getSharedQueuedThreads().isEmpty()); 204 } 205 206 /** 207 * Checks that sync has exactly the given (shared) queued threads. 208 */ 209 void assertHasSharedQueuedThreads(AbstractQueuedSynchronizer sync, 210 Thread... expected) { 211 assertHasQueuedThreads(sync, expected); 212 assertEquals(new HashSet<Thread>(sync.getSharedQueuedThreads()), 213 new HashSet<Thread>(sync.getQueuedThreads())); 214 assertEquals(0, sync.getExclusiveQueuedThreads().size()); 215 assertTrue(sync.getExclusiveQueuedThreads().isEmpty()); 216 } 217 218 /** 219 * Checks that condition c has exactly the given waiter threads, 220 * after acquiring mutex. 221 */ 222 void assertHasWaitersUnlocked(Mutex sync, ConditionObject c, 223 Thread... threads) { 224 sync.acquire(); 225 assertHasWaitersLocked(sync, c, threads); 226 sync.release(); 227 } 228 229 /** 230 * Checks that condition c has exactly the given waiter threads. 231 */ 232 void assertHasWaitersLocked(Mutex sync, ConditionObject c, 233 Thread... threads) { 234 assertEquals(threads.length > 0, sync.hasWaiters(c)); 235 assertEquals(threads.length, sync.getWaitQueueLength(c)); 236 assertEquals(threads.length == 0, sync.getWaitingThreads(c).isEmpty()); 237 assertEquals(threads.length, sync.getWaitingThreads(c).size()); 238 assertEquals(new HashSet<Thread>(sync.getWaitingThreads(c)), 239 new HashSet<Thread>(Arrays.asList(threads))); 240 } 241 242 enum AwaitMethod { await, awaitTimed, awaitNanos, awaitUntil } 243 244 /** 245 * Awaits condition using the specified AwaitMethod. 246 */ 247 void await(ConditionObject c, AwaitMethod awaitMethod) 248 throws InterruptedException { 249 long timeoutMillis = 2 * LONG_DELAY_MS; 250 switch (awaitMethod) { 251 case await: 252 c.await(); 253 break; 254 case awaitTimed: 255 assertTrue(c.await(timeoutMillis, MILLISECONDS)); 256 break; 257 case awaitNanos: 258 long timeoutNanos = MILLISECONDS.toNanos(timeoutMillis); 259 long nanosRemaining = c.awaitNanos(timeoutNanos); 260 assertTrue(nanosRemaining > 0); 261 break; 262 case awaitUntil: 263 assertTrue(c.awaitUntil(delayedDate(timeoutMillis))); 264 break; 265 default: 266 throw new AssertionError(); 267 } 268 } 269 270 /** 271 * Checks that awaiting the given condition times out (using the 272 * default timeout duration). 273 */ 274 void assertAwaitTimesOut(ConditionObject c, AwaitMethod awaitMethod) { 275 final long timeoutMillis = timeoutMillis(); 276 final long startTime; 277 try { 278 switch (awaitMethod) { 279 case awaitTimed: 280 startTime = System.nanoTime(); 281 assertFalse(c.await(timeoutMillis, MILLISECONDS)); 282 assertTrue(millisElapsedSince(startTime) >= timeoutMillis); 283 break; 284 case awaitNanos: 285 startTime = System.nanoTime(); 286 long timeoutNanos = MILLISECONDS.toNanos(timeoutMillis); 287 long nanosRemaining = c.awaitNanos(timeoutNanos); 288 assertTrue(nanosRemaining <= 0); 289 assertTrue(nanosRemaining > -MILLISECONDS.toNanos(LONG_DELAY_MS)); 290 assertTrue(millisElapsedSince(startTime) >= timeoutMillis); 291 break; 292 case awaitUntil: 293 // We shouldn't assume that nanoTime and currentTimeMillis 294 // use the same time source, so don't use nanoTime here. 295 java.util.Date delayedDate = delayedDate(timeoutMillis); 296 assertFalse(c.awaitUntil(delayedDate(timeoutMillis))); 297 assertTrue(new java.util.Date().getTime() >= delayedDate.getTime()); 298 break; 299 default: 300 throw new UnsupportedOperationException(); 301 } 302 } catch (InterruptedException ie) { threadUnexpectedException(ie); } 303 } 304 305 /** 306 * isHeldExclusively is false upon construction 307 */ 308 public void testIsHeldExclusively() { 309 Mutex sync = new Mutex(); 310 assertFalse(sync.isHeldExclusively()); 311 } 312 313 /** 314 * acquiring released sync succeeds 315 */ 316 public void testAcquire() { 317 Mutex sync = new Mutex(); 318 sync.acquire(); 319 assertTrue(sync.isHeldExclusively()); 320 sync.release(); 321 assertFalse(sync.isHeldExclusively()); 322 } 323 324 /** 325 * tryAcquire on a released sync succeeds 326 */ 327 public void testTryAcquire() { 328 Mutex sync = new Mutex(); 329 assertTrue(sync.tryAcquire()); 330 assertTrue(sync.isHeldExclusively()); 331 sync.release(); 332 assertFalse(sync.isHeldExclusively()); 333 } 334 335 /** 336 * hasQueuedThreads reports whether there are waiting threads 337 */ 338 public void testHasQueuedThreads() { 339 final Mutex sync = new Mutex(); 340 assertFalse(sync.hasQueuedThreads()); 341 sync.acquire(); 342 Thread t1 = newStartedThread(new InterruptedSyncRunnable(sync)); 343 waitForQueuedThread(sync, t1); 344 assertTrue(sync.hasQueuedThreads()); 345 Thread t2 = newStartedThread(new InterruptibleSyncRunnable(sync)); 346 waitForQueuedThread(sync, t2); 347 assertTrue(sync.hasQueuedThreads()); 348 t1.interrupt(); 349 awaitTermination(t1); 350 assertTrue(sync.hasQueuedThreads()); 351 sync.release(); 352 awaitTermination(t2); 353 assertFalse(sync.hasQueuedThreads()); 354 } 355 356 /** 357 * isQueued(null) throws NullPointerException 358 */ 359 public void testIsQueuedNPE() { 360 final Mutex sync = new Mutex(); 361 try { 362 sync.isQueued(null); 363 shouldThrow(); 364 } catch (NullPointerException success) {} 365 } 366 367 /** 368 * isQueued reports whether a thread is queued 369 */ 370 public void testIsQueued() { 371 final Mutex sync = new Mutex(); 372 Thread t1 = new Thread(new InterruptedSyncRunnable(sync)); 373 Thread t2 = new Thread(new InterruptibleSyncRunnable(sync)); 374 assertFalse(sync.isQueued(t1)); 375 assertFalse(sync.isQueued(t2)); 376 sync.acquire(); 377 t1.start(); 378 waitForQueuedThread(sync, t1); 379 assertTrue(sync.isQueued(t1)); 380 assertFalse(sync.isQueued(t2)); 381 t2.start(); 382 waitForQueuedThread(sync, t2); 383 assertTrue(sync.isQueued(t1)); 384 assertTrue(sync.isQueued(t2)); 385 t1.interrupt(); 386 awaitTermination(t1); 387 assertFalse(sync.isQueued(t1)); 388 assertTrue(sync.isQueued(t2)); 389 sync.release(); 390 awaitTermination(t2); 391 assertFalse(sync.isQueued(t1)); 392 assertFalse(sync.isQueued(t2)); 393 } 394 395 /** 396 * getFirstQueuedThread returns first waiting thread or null if none 397 */ 398 public void testGetFirstQueuedThread() { 399 final Mutex sync = new Mutex(); 400 assertNull(sync.getFirstQueuedThread()); 401 sync.acquire(); 402 Thread t1 = newStartedThread(new InterruptedSyncRunnable(sync)); 403 waitForQueuedThread(sync, t1); 404 assertEquals(t1, sync.getFirstQueuedThread()); 405 Thread t2 = newStartedThread(new InterruptibleSyncRunnable(sync)); 406 waitForQueuedThread(sync, t2); 407 assertEquals(t1, sync.getFirstQueuedThread()); 408 t1.interrupt(); 409 awaitTermination(t1); 410 assertEquals(t2, sync.getFirstQueuedThread()); 411 sync.release(); 412 awaitTermination(t2); 413 assertNull(sync.getFirstQueuedThread()); 414 } 415 416 /** 417 * hasContended reports false if no thread has ever blocked, else true 418 */ 419 public void testHasContended() { 420 final Mutex sync = new Mutex(); 421 assertFalse(sync.hasContended()); 422 sync.acquire(); 423 assertFalse(sync.hasContended()); 424 Thread t1 = newStartedThread(new InterruptedSyncRunnable(sync)); 425 waitForQueuedThread(sync, t1); 426 assertTrue(sync.hasContended()); 427 Thread t2 = newStartedThread(new InterruptibleSyncRunnable(sync)); 428 waitForQueuedThread(sync, t2); 429 assertTrue(sync.hasContended()); 430 t1.interrupt(); 431 awaitTermination(t1); 432 assertTrue(sync.hasContended()); 433 sync.release(); 434 awaitTermination(t2); 435 assertTrue(sync.hasContended()); 436 } 437 438 /** 439 * getQueuedThreads returns all waiting threads 440 */ 441 public void testGetQueuedThreads() { 442 final Mutex sync = new Mutex(); 443 Thread t1 = new Thread(new InterruptedSyncRunnable(sync)); 444 Thread t2 = new Thread(new InterruptibleSyncRunnable(sync)); 445 assertHasExclusiveQueuedThreads(sync, NO_THREADS); 446 sync.acquire(); 447 assertHasExclusiveQueuedThreads(sync, NO_THREADS); 448 t1.start(); 449 waitForQueuedThread(sync, t1); 450 assertHasExclusiveQueuedThreads(sync, t1); 451 assertTrue(sync.getQueuedThreads().contains(t1)); 452 assertFalse(sync.getQueuedThreads().contains(t2)); 453 t2.start(); 454 waitForQueuedThread(sync, t2); 455 assertHasExclusiveQueuedThreads(sync, t1, t2); 456 assertTrue(sync.getQueuedThreads().contains(t1)); 457 assertTrue(sync.getQueuedThreads().contains(t2)); 458 t1.interrupt(); 459 awaitTermination(t1); 460 assertHasExclusiveQueuedThreads(sync, t2); 461 sync.release(); 462 awaitTermination(t2); 463 assertHasExclusiveQueuedThreads(sync, NO_THREADS); 464 } 465 466 /** 467 * getExclusiveQueuedThreads returns all exclusive waiting threads 468 */ 469 public void testGetExclusiveQueuedThreads() { 470 final Mutex sync = new Mutex(); 471 Thread t1 = new Thread(new InterruptedSyncRunnable(sync)); 472 Thread t2 = new Thread(new InterruptibleSyncRunnable(sync)); 473 assertHasExclusiveQueuedThreads(sync, NO_THREADS); 474 sync.acquire(); 475 assertHasExclusiveQueuedThreads(sync, NO_THREADS); 476 t1.start(); 477 waitForQueuedThread(sync, t1); 478 assertHasExclusiveQueuedThreads(sync, t1); 479 assertTrue(sync.getExclusiveQueuedThreads().contains(t1)); 480 assertFalse(sync.getExclusiveQueuedThreads().contains(t2)); 481 t2.start(); 482 waitForQueuedThread(sync, t2); 483 assertHasExclusiveQueuedThreads(sync, t1, t2); 484 assertTrue(sync.getExclusiveQueuedThreads().contains(t1)); 485 assertTrue(sync.getExclusiveQueuedThreads().contains(t2)); 486 t1.interrupt(); 487 awaitTermination(t1); 488 assertHasExclusiveQueuedThreads(sync, t2); 489 sync.release(); 490 awaitTermination(t2); 491 assertHasExclusiveQueuedThreads(sync, NO_THREADS); 492 } 493 494 /** 495 * getSharedQueuedThreads does not include exclusively waiting threads 496 */ 497 public void testGetSharedQueuedThreads_Exclusive() { 498 final Mutex sync = new Mutex(); 499 assertTrue(sync.getSharedQueuedThreads().isEmpty()); 500 sync.acquire(); 501 assertTrue(sync.getSharedQueuedThreads().isEmpty()); 502 Thread t1 = newStartedThread(new InterruptedSyncRunnable(sync)); 503 waitForQueuedThread(sync, t1); 504 assertTrue(sync.getSharedQueuedThreads().isEmpty()); 505 Thread t2 = newStartedThread(new InterruptibleSyncRunnable(sync)); 506 waitForQueuedThread(sync, t2); 507 assertTrue(sync.getSharedQueuedThreads().isEmpty()); 508 t1.interrupt(); 509 awaitTermination(t1); 510 assertTrue(sync.getSharedQueuedThreads().isEmpty()); 511 sync.release(); 512 awaitTermination(t2); 513 assertTrue(sync.getSharedQueuedThreads().isEmpty()); 514 } 515 516 /** 517 * getSharedQueuedThreads returns all shared waiting threads 518 */ 519 public void testGetSharedQueuedThreads_Shared() { 520 final BooleanLatch l = new BooleanLatch(); 521 assertHasSharedQueuedThreads(l, NO_THREADS); 522 Thread t1 = newStartedThread(new CheckedInterruptedRunnable() { 523 public void realRun() throws InterruptedException { 524 l.acquireSharedInterruptibly(0); 525 }}); 526 waitForQueuedThread(l, t1); 527 assertHasSharedQueuedThreads(l, t1); 528 Thread t2 = newStartedThread(new CheckedRunnable() { 529 public void realRun() throws InterruptedException { 530 l.acquireSharedInterruptibly(0); 531 }}); 532 waitForQueuedThread(l, t2); 533 assertHasSharedQueuedThreads(l, t1, t2); 534 t1.interrupt(); 535 awaitTermination(t1); 536 assertHasSharedQueuedThreads(l, t2); 537 assertTrue(l.releaseShared(0)); 538 awaitTermination(t2); 539 assertHasSharedQueuedThreads(l, NO_THREADS); 540 } 541 542 /** 543 * tryAcquireNanos is interruptible 544 */ 545 public void testTryAcquireNanos_Interruptible() { 546 final Mutex sync = new Mutex(); 547 sync.acquire(); 548 Thread t = newStartedThread(new CheckedInterruptedRunnable() { 549 public void realRun() throws InterruptedException { 550 sync.tryAcquireNanos(MILLISECONDS.toNanos(2 * LONG_DELAY_MS)); 551 }}); 552 553 waitForQueuedThread(sync, t); 554 t.interrupt(); 555 awaitTermination(t); 556 } 557 558 /** 559 * tryAcquire on exclusively held sync fails 560 */ 561 public void testTryAcquireWhenSynced() { 562 final Mutex sync = new Mutex(); 563 sync.acquire(); 564 Thread t = newStartedThread(new CheckedRunnable() { 565 public void realRun() { 566 assertFalse(sync.tryAcquire()); 567 }}); 568 569 awaitTermination(t); 570 sync.release(); 571 } 572 573 /** 574 * tryAcquireNanos on an exclusively held sync times out 575 */ 576 public void testAcquireNanos_Timeout() { 577 final Mutex sync = new Mutex(); 578 sync.acquire(); 579 Thread t = newStartedThread(new CheckedRunnable() { 580 public void realRun() throws InterruptedException { 581 long startTime = System.nanoTime(); 582 long nanos = MILLISECONDS.toNanos(timeoutMillis()); 583 assertFalse(sync.tryAcquireNanos(nanos)); 584 assertTrue(millisElapsedSince(startTime) >= timeoutMillis()); 585 }}); 586 587 awaitTermination(t); 588 sync.release(); 589 } 590 591 /** 592 * getState is true when acquired and false when not 593 */ 594 public void testGetState() { 595 final Mutex sync = new Mutex(); 596 sync.acquire(); 597 assertTrue(sync.isHeldExclusively()); 598 sync.release(); 599 assertFalse(sync.isHeldExclusively()); 600 601 final BooleanLatch acquired = new BooleanLatch(); 602 final BooleanLatch done = new BooleanLatch(); 603 Thread t = newStartedThread(new CheckedRunnable() { 604 public void realRun() throws InterruptedException { 605 sync.acquire(); 606 assertTrue(acquired.releaseShared(0)); 607 done.acquireShared(0); 608 sync.release(); 609 }}); 610 611 acquired.acquireShared(0); 612 assertTrue(sync.isHeldExclusively()); 613 assertTrue(done.releaseShared(0)); 614 awaitTermination(t); 615 assertFalse(sync.isHeldExclusively()); 616 } 617 618 /** 619 * acquireInterruptibly succeeds when released, else is interruptible 620 */ 621 public void testAcquireInterruptibly() throws InterruptedException { 622 final Mutex sync = new Mutex(); 623 final BooleanLatch threadStarted = new BooleanLatch(); 624 sync.acquireInterruptibly(); 625 Thread t = newStartedThread(new CheckedInterruptedRunnable() { 626 public void realRun() throws InterruptedException { 627 assertTrue(threadStarted.releaseShared(0)); 628 sync.acquireInterruptibly(); 629 }}); 630 631 threadStarted.acquireShared(0); 632 waitForQueuedThread(sync, t); 633 t.interrupt(); 634 awaitTermination(t); 635 assertTrue(sync.isHeldExclusively()); 636 } 637 638 /** 639 * owns is true for a condition created by sync else false 640 */ 641 public void testOwns() { 642 final Mutex sync = new Mutex(); 643 final ConditionObject c = sync.newCondition(); 644 final Mutex sync2 = new Mutex(); 645 assertTrue(sync.owns(c)); 646 assertFalse(sync2.owns(c)); 647 } 648 649 /** 650 * Calling await without holding sync throws IllegalMonitorStateException 651 */ 652 public void testAwait_IMSE() { 653 final Mutex sync = new Mutex(); 654 final ConditionObject c = sync.newCondition(); 655 for (AwaitMethod awaitMethod : AwaitMethod.values()) { 656 long startTime = System.nanoTime(); 657 try { 658 await(c, awaitMethod); 659 shouldThrow(); 660 } catch (IllegalMonitorStateException success) { 661 } catch (InterruptedException e) { threadUnexpectedException(e); } 662 assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS); 663 } 664 } 665 666 /** 667 * Calling signal without holding sync throws IllegalMonitorStateException 668 */ 669 public void testSignal_IMSE() { 670 final Mutex sync = new Mutex(); 671 final ConditionObject c = sync.newCondition(); 672 try { 673 c.signal(); 674 shouldThrow(); 675 } catch (IllegalMonitorStateException success) {} 676 assertHasWaitersUnlocked(sync, c, NO_THREADS); 677 } 678 679 /** 680 * Calling signalAll without holding sync throws IllegalMonitorStateException 681 */ 682 public void testSignalAll_IMSE() { 683 final Mutex sync = new Mutex(); 684 final ConditionObject c = sync.newCondition(); 685 try { 686 c.signalAll(); 687 shouldThrow(); 688 } catch (IllegalMonitorStateException success) {} 689 } 690 691 /** 692 * await/awaitNanos/awaitUntil without a signal times out 693 */ 694 public void testAwaitTimed_Timeout() { testAwait_Timeout(AwaitMethod.awaitTimed); } 695 public void testAwaitNanos_Timeout() { testAwait_Timeout(AwaitMethod.awaitNanos); } 696 public void testAwaitUntil_Timeout() { testAwait_Timeout(AwaitMethod.awaitUntil); } 697 public void testAwait_Timeout(AwaitMethod awaitMethod) { 698 final Mutex sync = new Mutex(); 699 final ConditionObject c = sync.newCondition(); 700 sync.acquire(); 701 assertAwaitTimesOut(c, awaitMethod); 702 sync.release(); 703 } 704 705 /** 706 * await/awaitNanos/awaitUntil returns when signalled 707 */ 708 public void testSignal_await() { testSignal(AwaitMethod.await); } 709 public void testSignal_awaitTimed() { testSignal(AwaitMethod.awaitTimed); } 710 public void testSignal_awaitNanos() { testSignal(AwaitMethod.awaitNanos); } 711 public void testSignal_awaitUntil() { testSignal(AwaitMethod.awaitUntil); } 712 public void testSignal(final AwaitMethod awaitMethod) { 713 final Mutex sync = new Mutex(); 714 final ConditionObject c = sync.newCondition(); 715 final BooleanLatch acquired = new BooleanLatch(); 716 Thread t = newStartedThread(new CheckedRunnable() { 717 public void realRun() throws InterruptedException { 718 sync.acquire(); 719 assertTrue(acquired.releaseShared(0)); 720 await(c, awaitMethod); 721 sync.release(); 722 }}); 723 724 acquired.acquireShared(0); 725 sync.acquire(); 726 assertHasWaitersLocked(sync, c, t); 727 assertHasExclusiveQueuedThreads(sync, NO_THREADS); 728 c.signal(); 729 assertHasWaitersLocked(sync, c, NO_THREADS); 730 assertHasExclusiveQueuedThreads(sync, t); 731 sync.release(); 732 awaitTermination(t); 733 } 734 735 /** 736 * hasWaiters(null) throws NullPointerException 737 */ 738 public void testHasWaitersNPE() { 739 final Mutex sync = new Mutex(); 740 try { 741 sync.hasWaiters(null); 742 shouldThrow(); 743 } catch (NullPointerException success) {} 744 } 745 746 /** 747 * getWaitQueueLength(null) throws NullPointerException 748 */ 749 public void testGetWaitQueueLengthNPE() { 750 final Mutex sync = new Mutex(); 751 try { 752 sync.getWaitQueueLength(null); 753 shouldThrow(); 754 } catch (NullPointerException success) {} 755 } 756 757 /** 758 * getWaitingThreads(null) throws NullPointerException 759 */ 760 public void testGetWaitingThreadsNPE() { 761 final Mutex sync = new Mutex(); 762 try { 763 sync.getWaitingThreads(null); 764 shouldThrow(); 765 } catch (NullPointerException success) {} 766 } 767 768 /** 769 * hasWaiters throws IllegalArgumentException if not owned 770 */ 771 public void testHasWaitersIAE() { 772 final Mutex sync = new Mutex(); 773 final ConditionObject c = sync.newCondition(); 774 final Mutex sync2 = new Mutex(); 775 try { 776 sync2.hasWaiters(c); 777 shouldThrow(); 778 } catch (IllegalArgumentException success) {} 779 assertHasWaitersUnlocked(sync, c, NO_THREADS); 780 } 781 782 /** 783 * hasWaiters throws IllegalMonitorStateException if not synced 784 */ 785 public void testHasWaitersIMSE() { 786 final Mutex sync = new Mutex(); 787 final ConditionObject c = sync.newCondition(); 788 try { 789 sync.hasWaiters(c); 790 shouldThrow(); 791 } catch (IllegalMonitorStateException success) {} 792 assertHasWaitersUnlocked(sync, c, NO_THREADS); 793 } 794 795 /** 796 * getWaitQueueLength throws IllegalArgumentException if not owned 797 */ 798 public void testGetWaitQueueLengthIAE() { 799 final Mutex sync = new Mutex(); 800 final ConditionObject c = sync.newCondition(); 801 final Mutex sync2 = new Mutex(); 802 try { 803 sync2.getWaitQueueLength(c); 804 shouldThrow(); 805 } catch (IllegalArgumentException success) {} 806 assertHasWaitersUnlocked(sync, c, NO_THREADS); 807 } 808 809 /** 810 * getWaitQueueLength throws IllegalMonitorStateException if not synced 811 */ 812 public void testGetWaitQueueLengthIMSE() { 813 final Mutex sync = new Mutex(); 814 final ConditionObject c = sync.newCondition(); 815 try { 816 sync.getWaitQueueLength(c); 817 shouldThrow(); 818 } catch (IllegalMonitorStateException success) {} 819 assertHasWaitersUnlocked(sync, c, NO_THREADS); 820 } 821 822 /** 823 * getWaitingThreads throws IllegalArgumentException if not owned 824 */ 825 public void testGetWaitingThreadsIAE() { 826 final Mutex sync = new Mutex(); 827 final ConditionObject c = sync.newCondition(); 828 final Mutex sync2 = new Mutex(); 829 try { 830 sync2.getWaitingThreads(c); 831 shouldThrow(); 832 } catch (IllegalArgumentException success) {} 833 assertHasWaitersUnlocked(sync, c, NO_THREADS); 834 } 835 836 /** 837 * getWaitingThreads throws IllegalMonitorStateException if not synced 838 */ 839 public void testGetWaitingThreadsIMSE() { 840 final Mutex sync = new Mutex(); 841 final ConditionObject c = sync.newCondition(); 842 try { 843 sync.getWaitingThreads(c); 844 shouldThrow(); 845 } catch (IllegalMonitorStateException success) {} 846 assertHasWaitersUnlocked(sync, c, NO_THREADS); 847 } 848 849 /** 850 * hasWaiters returns true when a thread is waiting, else false 851 */ 852 public void testHasWaiters() { 853 final Mutex sync = new Mutex(); 854 final ConditionObject c = sync.newCondition(); 855 final BooleanLatch acquired = new BooleanLatch(); 856 Thread t = newStartedThread(new CheckedRunnable() { 857 public void realRun() throws InterruptedException { 858 sync.acquire(); 859 assertHasWaitersLocked(sync, c, NO_THREADS); 860 assertFalse(sync.hasWaiters(c)); 861 assertTrue(acquired.releaseShared(0)); 862 c.await(); 863 sync.release(); 864 }}); 865 866 acquired.acquireShared(0); 867 sync.acquire(); 868 assertHasWaitersLocked(sync, c, t); 869 assertHasExclusiveQueuedThreads(sync, NO_THREADS); 870 assertTrue(sync.hasWaiters(c)); 871 c.signal(); 872 assertHasWaitersLocked(sync, c, NO_THREADS); 873 assertHasExclusiveQueuedThreads(sync, t); 874 assertFalse(sync.hasWaiters(c)); 875 sync.release(); 876 877 awaitTermination(t); 878 assertHasWaitersUnlocked(sync, c, NO_THREADS); 879 } 880 881 /** 882 * getWaitQueueLength returns number of waiting threads 883 */ 884 public void testGetWaitQueueLength() { 885 final Mutex sync = new Mutex(); 886 final ConditionObject c = sync.newCondition(); 887 final BooleanLatch acquired1 = new BooleanLatch(); 888 final BooleanLatch acquired2 = new BooleanLatch(); 889 final Thread t1 = newStartedThread(new CheckedRunnable() { 890 public void realRun() throws InterruptedException { 891 sync.acquire(); 892 assertHasWaitersLocked(sync, c, NO_THREADS); 893 assertEquals(0, sync.getWaitQueueLength(c)); 894 assertTrue(acquired1.releaseShared(0)); 895 c.await(); 896 sync.release(); 897 }}); 898 acquired1.acquireShared(0); 899 sync.acquire(); 900 assertHasWaitersLocked(sync, c, t1); 901 assertEquals(1, sync.getWaitQueueLength(c)); 902 sync.release(); 903 904 final Thread t2 = newStartedThread(new CheckedRunnable() { 905 public void realRun() throws InterruptedException { 906 sync.acquire(); 907 assertHasWaitersLocked(sync, c, t1); 908 assertEquals(1, sync.getWaitQueueLength(c)); 909 assertTrue(acquired2.releaseShared(0)); 910 c.await(); 911 sync.release(); 912 }}); 913 acquired2.acquireShared(0); 914 sync.acquire(); 915 assertHasWaitersLocked(sync, c, t1, t2); 916 assertHasExclusiveQueuedThreads(sync, NO_THREADS); 917 assertEquals(2, sync.getWaitQueueLength(c)); 918 c.signalAll(); 919 assertHasWaitersLocked(sync, c, NO_THREADS); 920 assertHasExclusiveQueuedThreads(sync, t1, t2); 921 assertEquals(0, sync.getWaitQueueLength(c)); 922 sync.release(); 923 924 awaitTermination(t1); 925 awaitTermination(t2); 926 assertHasWaitersUnlocked(sync, c, NO_THREADS); 927 } 928 929 /** 930 * getWaitingThreads returns only and all waiting threads 931 */ 932 public void testGetWaitingThreads() { 933 final Mutex sync = new Mutex(); 934 final ConditionObject c = sync.newCondition(); 935 final BooleanLatch acquired1 = new BooleanLatch(); 936 final BooleanLatch acquired2 = new BooleanLatch(); 937 final Thread t1 = new Thread(new CheckedRunnable() { 938 public void realRun() throws InterruptedException { 939 sync.acquire(); 940 assertHasWaitersLocked(sync, c, NO_THREADS); 941 assertTrue(sync.getWaitingThreads(c).isEmpty()); 942 assertTrue(acquired1.releaseShared(0)); 943 c.await(); 944 sync.release(); 945 }}); 946 947 final Thread t2 = new Thread(new CheckedRunnable() { 948 public void realRun() throws InterruptedException { 949 sync.acquire(); 950 assertHasWaitersLocked(sync, c, t1); 951 assertTrue(sync.getWaitingThreads(c).contains(t1)); 952 assertFalse(sync.getWaitingThreads(c).isEmpty()); 953 assertEquals(1, sync.getWaitingThreads(c).size()); 954 assertTrue(acquired2.releaseShared(0)); 955 c.await(); 956 sync.release(); 957 }}); 958 959 sync.acquire(); 960 assertHasWaitersLocked(sync, c, NO_THREADS); 961 assertFalse(sync.getWaitingThreads(c).contains(t1)); 962 assertFalse(sync.getWaitingThreads(c).contains(t2)); 963 assertTrue(sync.getWaitingThreads(c).isEmpty()); 964 assertEquals(0, sync.getWaitingThreads(c).size()); 965 sync.release(); 966 967 t1.start(); 968 acquired1.acquireShared(0); 969 sync.acquire(); 970 assertHasWaitersLocked(sync, c, t1); 971 assertTrue(sync.getWaitingThreads(c).contains(t1)); 972 assertFalse(sync.getWaitingThreads(c).contains(t2)); 973 assertFalse(sync.getWaitingThreads(c).isEmpty()); 974 assertEquals(1, sync.getWaitingThreads(c).size()); 975 sync.release(); 976 977 t2.start(); 978 acquired2.acquireShared(0); 979 sync.acquire(); 980 assertHasWaitersLocked(sync, c, t1, t2); 981 assertHasExclusiveQueuedThreads(sync, NO_THREADS); 982 assertTrue(sync.getWaitingThreads(c).contains(t1)); 983 assertTrue(sync.getWaitingThreads(c).contains(t2)); 984 assertFalse(sync.getWaitingThreads(c).isEmpty()); 985 assertEquals(2, sync.getWaitingThreads(c).size()); 986 c.signalAll(); 987 assertHasWaitersLocked(sync, c, NO_THREADS); 988 assertHasExclusiveQueuedThreads(sync, t1, t2); 989 assertFalse(sync.getWaitingThreads(c).contains(t1)); 990 assertFalse(sync.getWaitingThreads(c).contains(t2)); 991 assertTrue(sync.getWaitingThreads(c).isEmpty()); 992 assertEquals(0, sync.getWaitingThreads(c).size()); 993 sync.release(); 994 995 awaitTermination(t1); 996 awaitTermination(t2); 997 assertHasWaitersUnlocked(sync, c, NO_THREADS); 998 } 999 1000 /** 1001 * awaitUninterruptibly is uninterruptible 1002 */ 1003 public void testAwaitUninterruptibly() { 1004 final Mutex sync = new Mutex(); 1005 final ConditionObject condition = sync.newCondition(); 1006 final BooleanLatch pleaseInterrupt = new BooleanLatch(); 1007 Thread t = newStartedThread(new CheckedRunnable() { 1008 public void realRun() { 1009 sync.acquire(); 1010 assertTrue(pleaseInterrupt.releaseShared(0)); 1011 condition.awaitUninterruptibly(); 1012 assertTrue(Thread.interrupted()); 1013 assertHasWaitersLocked(sync, condition, NO_THREADS); 1014 sync.release(); 1015 }}); 1016 1017 pleaseInterrupt.acquireShared(0); 1018 sync.acquire(); 1019 assertHasWaitersLocked(sync, condition, t); 1020 sync.release(); 1021 t.interrupt(); 1022 assertHasWaitersUnlocked(sync, condition, t); 1023 assertThreadBlocks(t, Thread.State.WAITING); 1024 sync.acquire(); 1025 assertHasWaitersLocked(sync, condition, t); 1026 assertHasExclusiveQueuedThreads(sync, NO_THREADS); 1027 condition.signal(); 1028 assertHasWaitersLocked(sync, condition, NO_THREADS); 1029 assertHasExclusiveQueuedThreads(sync, t); 1030 sync.release(); 1031 awaitTermination(t); 1032 } 1033 1034 /** 1035 * await/awaitNanos/awaitUntil is interruptible 1036 */ 1037 public void testInterruptible_await() { testInterruptible(AwaitMethod.await); } 1038 public void testInterruptible_awaitTimed() { testInterruptible(AwaitMethod.awaitTimed); } 1039 public void testInterruptible_awaitNanos() { testInterruptible(AwaitMethod.awaitNanos); } 1040 public void testInterruptible_awaitUntil() { testInterruptible(AwaitMethod.awaitUntil); } 1041 public void testInterruptible(final AwaitMethod awaitMethod) { 1042 final Mutex sync = new Mutex(); 1043 final ConditionObject c = sync.newCondition(); 1044 final BooleanLatch pleaseInterrupt = new BooleanLatch(); 1045 Thread t = newStartedThread(new CheckedInterruptedRunnable() { 1046 public void realRun() throws InterruptedException { 1047 sync.acquire(); 1048 assertTrue(pleaseInterrupt.releaseShared(0)); 1049 await(c, awaitMethod); 1050 }}); 1051 1052 pleaseInterrupt.acquireShared(0); 1053 t.interrupt(); 1054 awaitTermination(t); 1055 } 1056 1057 /** 1058 * signalAll wakes up all threads 1059 */ 1060 public void testSignalAll_await() { testSignalAll(AwaitMethod.await); } 1061 public void testSignalAll_awaitTimed() { testSignalAll(AwaitMethod.awaitTimed); } 1062 public void testSignalAll_awaitNanos() { testSignalAll(AwaitMethod.awaitNanos); } 1063 public void testSignalAll_awaitUntil() { testSignalAll(AwaitMethod.awaitUntil); } 1064 public void testSignalAll(final AwaitMethod awaitMethod) { 1065 final Mutex sync = new Mutex(); 1066 final ConditionObject c = sync.newCondition(); 1067 final BooleanLatch acquired1 = new BooleanLatch(); 1068 final BooleanLatch acquired2 = new BooleanLatch(); 1069 Thread t1 = newStartedThread(new CheckedRunnable() { 1070 public void realRun() throws InterruptedException { 1071 sync.acquire(); 1072 acquired1.releaseShared(0); 1073 await(c, awaitMethod); 1074 sync.release(); 1075 }}); 1076 1077 Thread t2 = newStartedThread(new CheckedRunnable() { 1078 public void realRun() throws InterruptedException { 1079 sync.acquire(); 1080 acquired2.releaseShared(0); 1081 await(c, awaitMethod); 1082 sync.release(); 1083 }}); 1084 1085 acquired1.acquireShared(0); 1086 acquired2.acquireShared(0); 1087 sync.acquire(); 1088 assertHasWaitersLocked(sync, c, t1, t2); 1089 assertHasExclusiveQueuedThreads(sync, NO_THREADS); 1090 c.signalAll(); 1091 assertHasWaitersLocked(sync, c, NO_THREADS); 1092 assertHasExclusiveQueuedThreads(sync, t1, t2); 1093 sync.release(); 1094 awaitTermination(t1); 1095 awaitTermination(t2); 1096 } 1097 1098 /** 1099 * toString indicates current state 1100 */ 1101 public void testToString() { 1102 Mutex sync = new Mutex(); 1103 assertTrue(sync.toString().contains("State = " + Mutex.UNLOCKED)); 1104 sync.acquire(); 1105 assertTrue(sync.toString().contains("State = " + Mutex.LOCKED)); 1106 } 1107 1108 /** 1109 * A serialized AQS deserializes with current state, but no queued threads 1110 */ 1111 public void testSerialization() { 1112 Mutex sync = new Mutex(); 1113 assertFalse(serialClone(sync).isHeldExclusively()); 1114 sync.acquire(); 1115 Thread t = newStartedThread(new InterruptedSyncRunnable(sync)); 1116 waitForQueuedThread(sync, t); 1117 assertTrue(sync.isHeldExclusively()); 1118 1119 Mutex clone = serialClone(sync); 1120 assertTrue(clone.isHeldExclusively()); 1121 assertHasExclusiveQueuedThreads(sync, t); 1122 assertHasExclusiveQueuedThreads(clone, NO_THREADS); 1123 t.interrupt(); 1124 awaitTermination(t); 1125 sync.release(); 1126 assertFalse(sync.isHeldExclusively()); 1127 assertTrue(clone.isHeldExclusively()); 1128 assertHasExclusiveQueuedThreads(sync, NO_THREADS); 1129 assertHasExclusiveQueuedThreads(clone, NO_THREADS); 1130 } 1131 1132 /** 1133 * tryReleaseShared setting state changes getState 1134 */ 1135 public void testGetStateWithReleaseShared() { 1136 final BooleanLatch l = new BooleanLatch(); 1137 assertFalse(l.isSignalled()); 1138 assertTrue(l.releaseShared(0)); 1139 assertTrue(l.isSignalled()); 1140 } 1141 1142 /** 1143 * releaseShared has no effect when already signalled 1144 */ 1145 public void testReleaseShared() { 1146 final BooleanLatch l = new BooleanLatch(); 1147 assertFalse(l.isSignalled()); 1148 assertTrue(l.releaseShared(0)); 1149 assertTrue(l.isSignalled()); 1150 assertTrue(l.releaseShared(0)); 1151 assertTrue(l.isSignalled()); 1152 } 1153 1154 /** 1155 * acquireSharedInterruptibly returns after release, but not before 1156 */ 1157 public void testAcquireSharedInterruptibly() { 1158 final BooleanLatch l = new BooleanLatch(); 1159 1160 Thread t = newStartedThread(new CheckedRunnable() { 1161 public void realRun() throws InterruptedException { 1162 assertFalse(l.isSignalled()); 1163 l.acquireSharedInterruptibly(0); 1164 assertTrue(l.isSignalled()); 1165 l.acquireSharedInterruptibly(0); 1166 assertTrue(l.isSignalled()); 1167 }}); 1168 1169 waitForQueuedThread(l, t); 1170 assertFalse(l.isSignalled()); 1171 assertThreadBlocks(t, Thread.State.WAITING); 1172 assertHasSharedQueuedThreads(l, t); 1173 assertTrue(l.releaseShared(0)); 1174 assertTrue(l.isSignalled()); 1175 awaitTermination(t); 1176 } 1177 1178 /** 1179 * tryAcquireSharedNanos returns after release, but not before 1180 */ 1181 public void testTryAcquireSharedNanos() { 1182 final BooleanLatch l = new BooleanLatch(); 1183 1184 Thread t = newStartedThread(new CheckedRunnable() { 1185 public void realRun() throws InterruptedException { 1186 assertFalse(l.isSignalled()); 1187 long nanos = MILLISECONDS.toNanos(2 * LONG_DELAY_MS); 1188 assertTrue(l.tryAcquireSharedNanos(0, nanos)); 1189 assertTrue(l.isSignalled()); 1190 assertTrue(l.tryAcquireSharedNanos(0, nanos)); 1191 assertTrue(l.isSignalled()); 1192 }}); 1193 1194 waitForQueuedThread(l, t); 1195 assertFalse(l.isSignalled()); 1196 assertThreadBlocks(t, Thread.State.TIMED_WAITING); 1197 assertTrue(l.releaseShared(0)); 1198 assertTrue(l.isSignalled()); 1199 awaitTermination(t); 1200 } 1201 1202 /** 1203 * acquireSharedInterruptibly is interruptible 1204 */ 1205 public void testAcquireSharedInterruptibly_Interruptible() { 1206 final BooleanLatch l = new BooleanLatch(); 1207 Thread t = newStartedThread(new CheckedInterruptedRunnable() { 1208 public void realRun() throws InterruptedException { 1209 assertFalse(l.isSignalled()); 1210 l.acquireSharedInterruptibly(0); 1211 }}); 1212 1213 waitForQueuedThread(l, t); 1214 assertFalse(l.isSignalled()); 1215 t.interrupt(); 1216 awaitTermination(t); 1217 assertFalse(l.isSignalled()); 1218 } 1219 1220 /** 1221 * tryAcquireSharedNanos is interruptible 1222 */ 1223 public void testTryAcquireSharedNanos_Interruptible() { 1224 final BooleanLatch l = new BooleanLatch(); 1225 Thread t = newStartedThread(new CheckedInterruptedRunnable() { 1226 public void realRun() throws InterruptedException { 1227 assertFalse(l.isSignalled()); 1228 long nanos = MILLISECONDS.toNanos(2 * LONG_DELAY_MS); 1229 l.tryAcquireSharedNanos(0, nanos); 1230 }}); 1231 1232 waitForQueuedThread(l, t); 1233 assertFalse(l.isSignalled()); 1234 t.interrupt(); 1235 awaitTermination(t); 1236 assertFalse(l.isSignalled()); 1237 } 1238 1239 /** 1240 * tryAcquireSharedNanos times out if not released before timeout 1241 */ 1242 public void testTryAcquireSharedNanos_Timeout() { 1243 final BooleanLatch l = new BooleanLatch(); 1244 final BooleanLatch observedQueued = new BooleanLatch(); 1245 Thread t = newStartedThread(new CheckedRunnable() { 1246 public void realRun() throws InterruptedException { 1247 assertFalse(l.isSignalled()); 1248 for (long millis = timeoutMillis(); 1249 !observedQueued.isSignalled(); 1250 millis *= 2) { 1251 long nanos = MILLISECONDS.toNanos(millis); 1252 long startTime = System.nanoTime(); 1253 assertFalse(l.tryAcquireSharedNanos(0, nanos)); 1254 assertTrue(millisElapsedSince(startTime) >= millis); 1255 } 1256 assertFalse(l.isSignalled()); 1257 }}); 1258 1259 waitForQueuedThread(l, t); 1260 observedQueued.releaseShared(0); 1261 assertFalse(l.isSignalled()); 1262 awaitTermination(t); 1263 assertFalse(l.isSignalled()); 1264 } 1265 1266 /** 1267 * awaitNanos/timed await with 0 wait times out immediately 1268 */ 1269 public void testAwait_Zero() throws InterruptedException { 1270 final Mutex sync = new Mutex(); 1271 final ConditionObject c = sync.newCondition(); 1272 sync.acquire(); 1273 assertTrue(c.awaitNanos(0L) <= 0); 1274 assertFalse(c.await(0L, NANOSECONDS)); 1275 sync.release(); 1276 } 1277 1278 /** 1279 * awaitNanos/timed await with maximum negative wait times does not underflow 1280 */ 1281 public void testAwait_NegativeInfinity() throws InterruptedException { 1282 final Mutex sync = new Mutex(); 1283 final ConditionObject c = sync.newCondition(); 1284 sync.acquire(); 1285 assertTrue(c.awaitNanos(Long.MIN_VALUE) <= 0); 1286 assertFalse(c.await(Long.MIN_VALUE, NANOSECONDS)); 1287 sync.release(); 1288 } 1289 1290 /** 1291 * JDK-8191483: AbstractQueuedSynchronizer cancel/cancel race 1292 * ant -Djsr166.tckTestClass=AbstractQueuedSynchronizerTest -Djsr166.methodFilter=testCancelCancelRace -Djsr166.runsPerTest=100 tck 1293 */ 1294 public void testCancelCancelRace() throws InterruptedException { 1295 class Sync extends AbstractQueuedSynchronizer { 1296 protected boolean tryAcquire(int acquires) { 1297 return !hasQueuedPredecessors() && compareAndSetState(0, 1); 1298 } 1299 protected boolean tryRelease(int releases) { 1300 return compareAndSetState(1, 0); 1301 } 1302 } 1303 1304 Sync s = new Sync(); 1305 s.acquire(1); // acquire to force other threads to enqueue 1306 1307 // try to trigger double cancel race with two background threads 1308 ArrayList<Thread> threads = new ArrayList<>(); 1309 Runnable failedAcquire = () -> { 1310 try { 1311 s.acquireInterruptibly(1); 1312 shouldThrow(); 1313 } catch (InterruptedException success) {} 1314 }; 1315 for (int i = 0; i < 2; i++) { 1316 Thread thread = new Thread(failedAcquire); 1317 thread.start(); 1318 threads.add(thread); 1319 } 1320 Thread.sleep(100); 1321 for (Thread thread : threads) thread.interrupt(); 1322 for (Thread thread : threads) awaitTermination(thread); 1323 1324 s.release(1); 1325 1326 // no one holds lock now, we should be able to acquire 1327 if (!s.tryAcquire(1)) 1328 throw new RuntimeException( 1329 String.format( 1330 "Broken: hasQueuedPredecessors=%s hasQueuedThreads=%s queueLength=%d firstQueuedThread=%s", 1331 s.hasQueuedPredecessors(), 1332 s.hasQueuedThreads(), 1333 s.getQueueLength(), 1334 s.getFirstQueuedThread())); 1335 } 1336 1337 /** 1338 * Tests scenario for 1339 * JDK-8191937: Lost interrupt in AbstractQueuedSynchronizer when tryAcquire methods throw 1340 */ 1341 public void testInterruptedFailingAcquire() throws InterruptedException { 1342 final RuntimeException ex = new RuntimeException(); 1343 1344 // A synchronizer only offering a choice of failure modes 1345 class Sync extends AbstractQueuedSynchronizer { 1346 boolean pleaseThrow; 1347 @Override protected boolean tryAcquire(int ignored) { 1348 if (pleaseThrow) throw ex; 1349 return false; 1350 } 1351 @Override protected int tryAcquireShared(int ignored) { 1352 if (pleaseThrow) throw ex; 1353 return -1; 1354 } 1355 @Override protected boolean tryRelease(int ignored) { 1356 return true; 1357 } 1358 @Override protected boolean tryReleaseShared(int ignored) { 1359 return true; 1360 } 1361 } 1362 1363 final Sync s = new Sync(); 1364 1365 final Thread thread = newStartedThread(new CheckedRunnable() { 1366 public void realRun() { 1367 try { 1368 if (ThreadLocalRandom.current().nextBoolean()) 1369 s.acquire(1); 1370 else 1371 s.acquireShared(1); 1372 shouldThrow(); 1373 } catch (Throwable t) { 1374 assertSame(ex, t); 1375 assertTrue(Thread.interrupted()); 1376 } 1377 }}); 1378 waitForThreadToEnterWaitState(thread); 1379 assertSame(thread, s.getFirstQueuedThread()); 1380 assertTrue(s.hasQueuedPredecessors()); 1381 assertTrue(s.hasQueuedThreads()); 1382 assertEquals(1, s.getQueueLength()); 1383 1384 s.pleaseThrow = true; 1385 thread.interrupt(); 1386 s.release(1); 1387 awaitTermination(thread); 1388 } 1389 1390 }