ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/AbstractQueuedSynchronizerTest.java
Revision: 1.14
Committed: Sat Jan 10 01:41:59 2004 UTC (20 years, 3 months ago) by dl
Branch: MAIN
Changes since 1.13: +37 -0 lines
Log Message:
Test toString

File Contents

# Content
1 /*
2 * Written by Doug Lea with assistance from members of JCP JSR-166
3 * Expert Group and released to the public domain, as explained at
4 * http://creativecommons.org/licenses/publicdomain
5 * Other contributors include Andrew Wright, Jeffrey Hayes,
6 * Pat Fisher, Mike Judd.
7 */
8
9
10 import junit.framework.*;
11 import java.util.*;
12 import java.util.concurrent.*;
13 import java.util.concurrent.locks.*;
14 import java.io.*;
15
16 public class AbstractQueuedSynchronizerTest extends JSR166TestCase {
17 public static void main(String[] args) {
18 junit.textui.TestRunner.run (suite());
19 }
20 public static Test suite() {
21 return new TestSuite(AbstractQueuedSynchronizerTest.class);
22 }
23
24 /**
25 * A simple mutex class, adapted from the
26 * AbstractQueuedSynchronizer javadoc. Exclusive acquire tests
27 * exercise this as a sample user extension. Other
28 * methods/features of AbstractQueuedSynchronizerTest are tested
29 * via other test classes, including those for ReentrantLock,
30 * ReentrantReadWriteLock, and Semaphore
31 */
32 static class Mutex extends AbstractQueuedSynchronizer {
33 public boolean isLocked() { return getState() == 1; }
34
35 public boolean tryAcquireExclusive(int acquires) {
36 assertTrue(acquires == 1);
37 return compareAndSetState(0, 1);
38 }
39
40 public boolean tryReleaseExclusive(int releases) {
41 setState(0);
42 return true;
43 }
44
45 public void checkConditionAccess(Thread thread) {
46 if (getState() == 0) throw new IllegalMonitorStateException();
47 }
48
49 public ConditionObject newCondition() { return new ConditionObject(); }
50
51 public void lock() {
52 acquireExclusiveUninterruptibly(1);
53 }
54
55 }
56
57
58 /**
59 * A simple latch class, to test shared mode.
60 */
61 static class BooleanLatch extends AbstractQueuedSynchronizer {
62 public boolean isSignalled() { return getState() != 0; }
63
64 public int tryAcquireShared(int ignore) {
65 return isSignalled()? 1 : -1;
66 }
67
68 public boolean tryReleaseShared(int ignore) {
69 setState(1);
70 return true;
71 }
72 }
73
74 /**
75 * A runnable calling acquireExclusiveInterruptibly
76 */
77 class InterruptibleLockRunnable implements Runnable {
78 final Mutex lock;
79 InterruptibleLockRunnable(Mutex l) { lock = l; }
80 public void run() {
81 try {
82 lock.acquireExclusiveInterruptibly(1);
83 } catch(InterruptedException success){}
84 }
85 }
86
87
88 /**
89 * A runnable calling acquireExclusiveInterruptibly that expects to be
90 * interrupted
91 */
92 class InterruptedLockRunnable implements Runnable {
93 final Mutex lock;
94 InterruptedLockRunnable(Mutex l) { lock = l; }
95 public void run() {
96 try {
97 lock.acquireExclusiveInterruptibly(1);
98 threadShouldThrow();
99 } catch(InterruptedException success){}
100 }
101 }
102
103 /**
104 * acquireExclusiveUninterruptiblying an releaseExclusiveed lock succeeds
105 */
106 public void testAcquireExclusiveUninterruptibly() {
107 Mutex rl = new Mutex();
108 rl.acquireExclusiveUninterruptibly(1);
109 assertTrue(rl.isLocked());
110 rl.releaseExclusive(1);
111 }
112
113 /**
114 * tryAcquireExclusive on an releaseExclusiveed lock succeeds
115 */
116 public void testTryAcquireExclusive() {
117 Mutex rl = new Mutex();
118 assertTrue(rl.tryAcquireExclusive(1));
119 assertTrue(rl.isLocked());
120 rl.releaseExclusive(1);
121 }
122
123 /**
124 * hasQueuedThreads reports whether there are waiting threads
125 */
126 public void testhasQueuedThreads() {
127 final Mutex lock = new Mutex();
128 Thread t1 = new Thread(new InterruptedLockRunnable(lock));
129 Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
130 try {
131 assertFalse(lock.hasQueuedThreads());
132 lock.acquireExclusiveUninterruptibly(1);
133 t1.start();
134 Thread.sleep(SHORT_DELAY_MS);
135 assertTrue(lock.hasQueuedThreads());
136 t2.start();
137 Thread.sleep(SHORT_DELAY_MS);
138 assertTrue(lock.hasQueuedThreads());
139 t1.interrupt();
140 Thread.sleep(SHORT_DELAY_MS);
141 assertTrue(lock.hasQueuedThreads());
142 lock.releaseExclusive(1);
143 Thread.sleep(SHORT_DELAY_MS);
144 assertFalse(lock.hasQueuedThreads());
145 t1.join();
146 t2.join();
147 } catch(Exception e){
148 unexpectedException();
149 }
150 }
151
152 /**
153 * isQueued(null) throws NPE
154 */
155 public void testIsQueuedNPE() {
156 final Mutex lock = new Mutex();
157 try {
158 lock.isQueued(null);
159 shouldThrow();
160 } catch (NullPointerException success) {
161 }
162 }
163
164 /**
165 * isQueued reports whether a thread is queued.
166 */
167 public void testIsQueued() {
168 final Mutex lock = new Mutex();
169 Thread t1 = new Thread(new InterruptedLockRunnable(lock));
170 Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
171 try {
172 assertFalse(lock.isQueued(t1));
173 assertFalse(lock.isQueued(t2));
174 lock.acquireExclusiveUninterruptibly(1);
175 t1.start();
176 Thread.sleep(SHORT_DELAY_MS);
177 assertTrue(lock.isQueued(t1));
178 t2.start();
179 Thread.sleep(SHORT_DELAY_MS);
180 assertTrue(lock.isQueued(t1));
181 assertTrue(lock.isQueued(t2));
182 t1.interrupt();
183 Thread.sleep(SHORT_DELAY_MS);
184 assertFalse(lock.isQueued(t1));
185 assertTrue(lock.isQueued(t2));
186 lock.releaseExclusive(1);
187 Thread.sleep(SHORT_DELAY_MS);
188 assertFalse(lock.isQueued(t1));
189 assertFalse(lock.isQueued(t2));
190 t1.join();
191 t2.join();
192 } catch(Exception e){
193 unexpectedException();
194 }
195 }
196
197 /**
198 * getFirstQueuedThread returns first waiting thread or null is none
199 */
200 public void testGetFirstQueuedThread() {
201 final Mutex lock = new Mutex();
202 Thread t1 = new Thread(new InterruptedLockRunnable(lock));
203 Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
204 try {
205 assertNull(lock.getFirstQueuedThread());
206 lock.acquireExclusiveUninterruptibly(1);
207 t1.start();
208 Thread.sleep(SHORT_DELAY_MS);
209 assertEquals(t1, lock.getFirstQueuedThread());
210 t2.start();
211 Thread.sleep(SHORT_DELAY_MS);
212 assertEquals(t1, lock.getFirstQueuedThread());
213 t1.interrupt();
214 Thread.sleep(SHORT_DELAY_MS);
215 assertEquals(t2, lock.getFirstQueuedThread());
216 lock.releaseExclusive(1);
217 Thread.sleep(SHORT_DELAY_MS);
218 assertNull(lock.getFirstQueuedThread());
219 t1.join();
220 t2.join();
221 } catch(Exception e){
222 unexpectedException();
223 }
224 }
225
226
227 /**
228 * hasContended reports false if no thread has ever blocked, else true
229 */
230 public void testHasContended() {
231 final Mutex lock = new Mutex();
232 Thread t1 = new Thread(new InterruptedLockRunnable(lock));
233 Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
234 try {
235 assertFalse(lock.hasContended());
236 lock.acquireExclusiveUninterruptibly(1);
237 t1.start();
238 Thread.sleep(SHORT_DELAY_MS);
239 assertTrue(lock.hasContended());
240 t2.start();
241 Thread.sleep(SHORT_DELAY_MS);
242 assertTrue(lock.hasContended());
243 t1.interrupt();
244 Thread.sleep(SHORT_DELAY_MS);
245 assertTrue(lock.hasContended());
246 lock.releaseExclusive(1);
247 Thread.sleep(SHORT_DELAY_MS);
248 assertTrue(lock.hasContended());
249 t1.join();
250 t2.join();
251 } catch(Exception e){
252 unexpectedException();
253 }
254 }
255
256 /**
257 * acquireExclusiveNanos is interruptible.
258 */
259 public void testInterruptedException2() {
260 final Mutex lock = new Mutex();
261 lock.acquireExclusiveUninterruptibly(1);
262 Thread t = new Thread(new Runnable() {
263 public void run() {
264 try {
265 lock.acquireExclusiveNanos(1, MEDIUM_DELAY_MS * 1000 * 1000);
266 threadShouldThrow();
267 } catch(InterruptedException success){}
268 }
269 });
270 try {
271 t.start();
272 t.interrupt();
273 } catch(Exception e){
274 unexpectedException();
275 }
276 }
277
278
279 /**
280 * TryAcquireExclusive on a locked lock fails
281 */
282 public void testTryAcquireExclusiveWhenLocked() {
283 final Mutex lock = new Mutex();
284 lock.acquireExclusiveUninterruptibly(1);
285 Thread t = new Thread(new Runnable() {
286 public void run() {
287 threadAssertFalse(lock.tryAcquireExclusive(1));
288 }
289 });
290 try {
291 t.start();
292 t.join();
293 lock.releaseExclusive(1);
294 } catch(Exception e){
295 unexpectedException();
296 }
297 }
298
299 /**
300 * acquireExclusiveNanos on a locked lock times out
301 */
302 public void testAcquireExclusiveNanos_Timeout() {
303 final Mutex lock = new Mutex();
304 lock.acquireExclusiveUninterruptibly(1);
305 Thread t = new Thread(new Runnable() {
306 public void run() {
307 try {
308 threadAssertFalse(lock.acquireExclusiveNanos(1, 1000 * 1000));
309 } catch (Exception ex) {
310 threadUnexpectedException();
311 }
312 }
313 });
314 try {
315 t.start();
316 t.join();
317 lock.releaseExclusive(1);
318 } catch(Exception e){
319 unexpectedException();
320 }
321 }
322
323
324 /**
325 * getState is true when acquired and false when not
326 */
327 public void testGetState() {
328 final Mutex lock = new Mutex();
329 lock.acquireExclusiveUninterruptibly(1);
330 assertTrue(lock.isLocked());
331 lock.releaseExclusive(1);
332 assertFalse(lock.isLocked());
333 Thread t = new Thread(new Runnable() {
334 public void run() {
335 lock.acquireExclusiveUninterruptibly(1);
336 try {
337 Thread.sleep(SMALL_DELAY_MS);
338 }
339 catch(Exception e) {
340 threadUnexpectedException();
341 }
342 lock.releaseExclusive(1);
343 }
344 });
345 try {
346 t.start();
347 Thread.sleep(SHORT_DELAY_MS);
348 assertTrue(lock.isLocked());
349 t.join();
350 assertFalse(lock.isLocked());
351 } catch(Exception e){
352 unexpectedException();
353 }
354 }
355
356
357 /**
358 * acquireExclusiveInterruptibly is interruptible.
359 */
360 public void testAcquireInterruptibly1() {
361 final Mutex lock = new Mutex();
362 lock.acquireExclusiveUninterruptibly(1);
363 Thread t = new Thread(new InterruptedLockRunnable(lock));
364 try {
365 t.start();
366 t.interrupt();
367 lock.releaseExclusive(1);
368 t.join();
369 } catch(Exception e){
370 unexpectedException();
371 }
372 }
373
374 /**
375 * acquireExclusiveInterruptibly succeeds when released, else is interruptible
376 */
377 public void testAcquireInterruptibly2() {
378 final Mutex lock = new Mutex();
379 try {
380 lock.acquireExclusiveInterruptibly(1);
381 } catch(Exception e) {
382 unexpectedException();
383 }
384 Thread t = new Thread(new InterruptedLockRunnable(lock));
385 try {
386 t.start();
387 t.interrupt();
388 assertTrue(lock.isLocked());
389 t.join();
390 } catch(Exception e){
391 unexpectedException();
392 }
393 }
394
395 /**
396 * owns is true for a condition created by lock else false
397 */
398 public void testOwns() {
399 final Mutex lock = new Mutex();
400 final AbstractQueuedSynchronizer.ConditionObject c = lock.newCondition();
401 final Mutex lock2 = new Mutex();
402 assertTrue(lock.owns(c));
403 assertFalse(lock2.owns(c));
404 }
405
406 /**
407 * Calling await without holding lock throws IllegalMonitorStateException
408 */
409 public void testAwait_IllegalMonitor() {
410 final Mutex lock = new Mutex();
411 final Condition c = lock.newCondition();
412 try {
413 c.await();
414 shouldThrow();
415 }
416 catch (IllegalMonitorStateException success) {
417 }
418 catch (Exception ex) {
419 unexpectedException();
420 }
421 }
422
423 /**
424 * Calling signal without holding lock throws IllegalMonitorStateException
425 */
426 public void testSignal_IllegalMonitor() {
427 final Mutex lock = new Mutex();
428 final Condition c = lock.newCondition();
429 try {
430 c.signal();
431 shouldThrow();
432 }
433 catch (IllegalMonitorStateException success) {
434 }
435 catch (Exception ex) {
436 unexpectedException();
437 }
438 }
439
440 /**
441 * awaitNanos without a signal times out
442 */
443 public void testAwaitNanos_Timeout() {
444 final Mutex lock = new Mutex();
445 final Condition c = lock.newCondition();
446 try {
447 lock.acquireExclusiveUninterruptibly(1);
448 long t = c.awaitNanos(100);
449 assertTrue(t <= 0);
450 lock.releaseExclusive(1);
451 }
452 catch (Exception ex) {
453 unexpectedException();
454 }
455 }
456
457 /**
458 * timed await without a signal times out
459 */
460 public void testAwait_Timeout() {
461 final Mutex lock = new Mutex();
462 final Condition c = lock.newCondition();
463 try {
464 lock.acquireExclusiveUninterruptibly(1);
465 assertFalse(c.await(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
466 lock.releaseExclusive(1);
467 }
468 catch (Exception ex) {
469 unexpectedException();
470 }
471 }
472
473 /**
474 * awaitUntil without a signal times out
475 */
476 public void testAwaitUntil_Timeout() {
477 final Mutex lock = new Mutex();
478 final Condition c = lock.newCondition();
479 try {
480 lock.acquireExclusiveUninterruptibly(1);
481 java.util.Date d = new java.util.Date();
482 assertFalse(c.awaitUntil(new java.util.Date(d.getTime() + 10)));
483 lock.releaseExclusive(1);
484 }
485 catch (Exception ex) {
486 unexpectedException();
487 }
488 }
489
490 /**
491 * await returns when signalled
492 */
493 public void testAwait() {
494 final Mutex lock = new Mutex();
495 final Condition c = lock.newCondition();
496 Thread t = new Thread(new Runnable() {
497 public void run() {
498 try {
499 lock.acquireExclusiveUninterruptibly(1);
500 c.await();
501 lock.releaseExclusive(1);
502 }
503 catch(InterruptedException e) {
504 threadUnexpectedException();
505 }
506 }
507 });
508
509 try {
510 t.start();
511 Thread.sleep(SHORT_DELAY_MS);
512 lock.acquireExclusiveUninterruptibly(1);
513 c.signal();
514 lock.releaseExclusive(1);
515 t.join(SHORT_DELAY_MS);
516 assertFalse(t.isAlive());
517 }
518 catch (Exception ex) {
519 unexpectedException();
520 }
521 }
522
523 /**
524 * toString indicates current state
525 */
526 public void testToString() {
527 Mutex lock = new Mutex();
528 String us = lock.toString();
529 assertTrue(us.indexOf("State = 0") >= 0);
530 lock.acquireExclusiveUninterruptibly(1);
531 String ls = lock.toString();
532 assertTrue(ls.indexOf("State = 1") >= 0);
533 }
534
535 /**
536 * A serialized AQS deserializes with current state
537 */
538 public void testSerialization() {
539 Mutex l = new Mutex();
540 l.acquireExclusiveUninterruptibly(1);
541 assertTrue(l.isLocked());
542
543 try {
544 ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
545 ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout));
546 out.writeObject(l);
547 out.close();
548
549 ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
550 ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
551 Mutex r = (Mutex) in.readObject();
552 assertTrue(r.isLocked());
553 } catch(Exception e){
554 e.printStackTrace();
555 unexpectedException();
556 }
557 }
558
559
560 /**
561 * Latch isSignalled initially returns false, then true after release
562 */
563 public void testLatchIsSignalled() {
564 final BooleanLatch l = new BooleanLatch();
565 assertFalse(l.isSignalled());
566 l.releaseShared(0);
567 assertTrue(l.isSignalled());
568 }
569
570 /**
571 * release and has no effect when already signalled
572 */
573 public void testReleaseShared() {
574 final BooleanLatch l = new BooleanLatch();
575 assertFalse(l.isSignalled());
576 l.releaseShared(0);
577 assertTrue(l.isSignalled());
578 l.releaseShared(0);
579 assertTrue(l.isSignalled());
580 }
581
582 /**
583 * acquireSharedInterruptibly returns after release, but not before
584 */
585 public void testAcquireSharedInterruptibly() {
586 final BooleanLatch l = new BooleanLatch();
587
588 Thread t = new Thread(new Runnable() {
589 public void run() {
590 try {
591 threadAssertFalse(l.isSignalled());
592 l.acquireSharedInterruptibly(0);
593 threadAssertTrue(l.isSignalled());
594 } catch(InterruptedException e){
595 threadUnexpectedException();
596 }
597 }
598 });
599 try {
600 t.start();
601 assertFalse(l.isSignalled());
602 Thread.sleep(SHORT_DELAY_MS);
603 l.releaseShared(0);
604 assertTrue(l.isSignalled());
605 t.join();
606 } catch (InterruptedException e){
607 unexpectedException();
608 }
609 }
610
611
612 /**
613 * acquireSharedTimed returns after release
614 */
615 public void testAsquireSharedTimed() {
616 final BooleanLatch l = new BooleanLatch();
617
618 Thread t = new Thread(new Runnable() {
619 public void run() {
620 try {
621 threadAssertFalse(l.isSignalled());
622 threadAssertTrue(l.acquireSharedNanos(0, MEDIUM_DELAY_MS* 1000 * 1000));
623 threadAssertTrue(l.isSignalled());
624
625 } catch(InterruptedException e){
626 threadUnexpectedException();
627 }
628 }
629 });
630 try {
631 t.start();
632 assertFalse(l.isSignalled());
633 Thread.sleep(SHORT_DELAY_MS);
634 l.releaseShared(0);
635 assertTrue(l.isSignalled());
636 t.join();
637 } catch (InterruptedException e){
638 unexpectedException();
639 }
640 }
641
642 /**
643 * acquireSharedInterruptibly throws IE if interrupted before released
644 */
645 public void testAcquireSharedInterruptibly_InterruptedException() {
646 final BooleanLatch l = new BooleanLatch();
647 Thread t = new Thread(new Runnable() {
648 public void run() {
649 try {
650 threadAssertFalse(l.isSignalled());
651 l.acquireSharedInterruptibly(0);
652 threadShouldThrow();
653 } catch(InterruptedException success){}
654 }
655 });
656 t.start();
657 try {
658 assertFalse(l.isSignalled());
659 t.interrupt();
660 t.join();
661 } catch (InterruptedException e){
662 unexpectedException();
663 }
664 }
665
666 /**
667 * acquireSharedTimed throws IE if interrupted before released
668 */
669 public void testAcquireSharedNanos_InterruptedException() {
670 final BooleanLatch l = new BooleanLatch();
671 Thread t = new Thread(new Runnable() {
672 public void run() {
673 try {
674 threadAssertFalse(l.isSignalled());
675 l.acquireSharedNanos(0, SMALL_DELAY_MS* 1000 * 1000);
676 threadShouldThrow();
677 } catch(InterruptedException success){}
678 }
679 });
680 t.start();
681 try {
682 Thread.sleep(SHORT_DELAY_MS);
683 assertFalse(l.isSignalled());
684 t.interrupt();
685 t.join();
686 } catch (InterruptedException e){
687 unexpectedException();
688 }
689 }
690
691 /**
692 * acquireSharedTimed times out if not released before timeout
693 */
694 public void testAcquireSharedNanos_Timeout() {
695 final BooleanLatch l = new BooleanLatch();
696 Thread t = new Thread(new Runnable() {
697 public void run() {
698 try {
699 threadAssertFalse(l.isSignalled());
700 threadAssertFalse(l.acquireSharedNanos(0, SMALL_DELAY_MS* 1000 * 1000));
701 } catch(InterruptedException ie){
702 threadUnexpectedException();
703 }
704 }
705 });
706 t.start();
707 try {
708 Thread.sleep(SHORT_DELAY_MS);
709 assertFalse(l.isSignalled());
710 t.join();
711 } catch (InterruptedException e){
712 unexpectedException();
713 }
714 }
715
716
717 }