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/publicdomain/zero/1.0/ 5 */ 6 7package jsr166; 8 9import static java.util.concurrent.TimeUnit.MILLISECONDS; 10 11import java.util.ArrayList; 12import java.util.List; 13import java.util.concurrent.BlockingQueue; 14import java.util.concurrent.Callable; 15import java.util.concurrent.CountDownLatch; 16import java.util.concurrent.Delayed; 17import java.util.concurrent.ExecutionException; 18import java.util.concurrent.Executors; 19import java.util.concurrent.ExecutorService; 20import java.util.concurrent.Future; 21import java.util.concurrent.RejectedExecutionException; 22import java.util.concurrent.RejectedExecutionHandler; 23import java.util.concurrent.RunnableScheduledFuture; 24import java.util.concurrent.ScheduledFuture; 25import java.util.concurrent.ScheduledThreadPoolExecutor; 26import java.util.concurrent.ThreadFactory; 27import java.util.concurrent.ThreadPoolExecutor; 28import java.util.concurrent.TimeoutException; 29import java.util.concurrent.TimeUnit; 30import java.util.concurrent.atomic.AtomicInteger; 31 32import junit.framework.Test; 33import junit.framework.TestSuite; 34 35public class ScheduledExecutorSubclassTest extends JSR166TestCase { 36 // android-note: Removed because the CTS runner does a bad job of 37 // retrying tests that have suite() declarations. 38 // 39 // public static void main(String[] args) { 40 // main(suite(), args); 41 // } 42 // public static Test suite() { 43 // return new TestSuite(...); 44 // } 45 46 static class CustomTask<V> implements RunnableScheduledFuture<V> { 47 RunnableScheduledFuture<V> task; 48 volatile boolean ran; 49 CustomTask(RunnableScheduledFuture<V> t) { task = t; } 50 public boolean isPeriodic() { return task.isPeriodic(); } 51 public void run() { 52 ran = true; 53 task.run(); 54 } 55 public long getDelay(TimeUnit unit) { return task.getDelay(unit); } 56 public int compareTo(Delayed t) { 57 return task.compareTo(((CustomTask)t).task); 58 } 59 public boolean cancel(boolean mayInterruptIfRunning) { 60 return task.cancel(mayInterruptIfRunning); 61 } 62 public boolean isCancelled() { return task.isCancelled(); } 63 public boolean isDone() { return task.isDone(); } 64 public V get() throws InterruptedException, ExecutionException { 65 V v = task.get(); 66 assertTrue(ran); 67 return v; 68 } 69 public V get(long time, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { 70 V v = task.get(time, unit); 71 assertTrue(ran); 72 return v; 73 } 74 } 75 76 public class CustomExecutor extends ScheduledThreadPoolExecutor { 77 78 protected <V> RunnableScheduledFuture<V> decorateTask(Runnable r, RunnableScheduledFuture<V> task) { 79 return new CustomTask<V>(task); 80 } 81 82 protected <V> RunnableScheduledFuture<V> decorateTask(Callable<V> c, RunnableScheduledFuture<V> task) { 83 return new CustomTask<V>(task); 84 } 85 CustomExecutor(int corePoolSize) { super(corePoolSize); } 86 CustomExecutor(int corePoolSize, RejectedExecutionHandler handler) { 87 super(corePoolSize, handler); 88 } 89 90 CustomExecutor(int corePoolSize, ThreadFactory threadFactory) { 91 super(corePoolSize, threadFactory); 92 } 93 CustomExecutor(int corePoolSize, ThreadFactory threadFactory, 94 RejectedExecutionHandler handler) { 95 super(corePoolSize, threadFactory, handler); 96 } 97 98 } 99 100 /** 101 * execute successfully executes a runnable 102 */ 103 public void testExecute() throws InterruptedException { 104 CustomExecutor p = new CustomExecutor(1); 105 final CountDownLatch done = new CountDownLatch(1); 106 final Runnable task = new CheckedRunnable() { 107 public void realRun() { 108 done.countDown(); 109 }}; 110 try { 111 p.execute(task); 112 assertTrue(done.await(SMALL_DELAY_MS, MILLISECONDS)); 113 } finally { 114 joinPool(p); 115 } 116 } 117 118 /** 119 * delayed schedule of callable successfully executes after delay 120 */ 121 public void testSchedule1() throws Exception { 122 CustomExecutor p = new CustomExecutor(1); 123 final long startTime = System.nanoTime(); 124 final CountDownLatch done = new CountDownLatch(1); 125 try { 126 Callable task = new CheckedCallable<Boolean>() { 127 public Boolean realCall() { 128 done.countDown(); 129 assertTrue(millisElapsedSince(startTime) >= timeoutMillis()); 130 return Boolean.TRUE; 131 }}; 132 Future f = p.schedule(task, timeoutMillis(), MILLISECONDS); 133 assertSame(Boolean.TRUE, f.get()); 134 assertTrue(millisElapsedSince(startTime) >= timeoutMillis()); 135 assertTrue(done.await(0L, MILLISECONDS)); 136 } finally { 137 joinPool(p); 138 } 139 } 140 141 /** 142 * delayed schedule of runnable successfully executes after delay 143 */ 144 public void testSchedule3() throws Exception { 145 CustomExecutor p = new CustomExecutor(1); 146 final long startTime = System.nanoTime(); 147 final CountDownLatch done = new CountDownLatch(1); 148 try { 149 Runnable task = new CheckedRunnable() { 150 public void realRun() { 151 done.countDown(); 152 assertTrue(millisElapsedSince(startTime) >= timeoutMillis()); 153 }}; 154 Future f = p.schedule(task, timeoutMillis(), MILLISECONDS); 155 await(done); 156 assertNull(f.get(LONG_DELAY_MS, MILLISECONDS)); 157 assertTrue(millisElapsedSince(startTime) >= timeoutMillis()); 158 } finally { 159 joinPool(p); 160 } 161 } 162 163 /** 164 * scheduleAtFixedRate executes runnable after given initial delay 165 */ 166 public void testSchedule4() throws InterruptedException { 167 CustomExecutor p = new CustomExecutor(1); 168 final long startTime = System.nanoTime(); 169 final CountDownLatch done = new CountDownLatch(1); 170 try { 171 Runnable task = new CheckedRunnable() { 172 public void realRun() { 173 done.countDown(); 174 assertTrue(millisElapsedSince(startTime) >= timeoutMillis()); 175 }}; 176 ScheduledFuture f = 177 p.scheduleAtFixedRate(task, timeoutMillis(), 178 LONG_DELAY_MS, MILLISECONDS); 179 await(done); 180 assertTrue(millisElapsedSince(startTime) >= timeoutMillis()); 181 f.cancel(true); 182 } finally { 183 joinPool(p); 184 } 185 } 186 187 /** 188 * scheduleWithFixedDelay executes runnable after given initial delay 189 */ 190 public void testSchedule5() throws InterruptedException { 191 CustomExecutor p = new CustomExecutor(1); 192 final long startTime = System.nanoTime(); 193 final CountDownLatch done = new CountDownLatch(1); 194 try { 195 Runnable task = new CheckedRunnable() { 196 public void realRun() { 197 done.countDown(); 198 assertTrue(millisElapsedSince(startTime) >= timeoutMillis()); 199 }}; 200 ScheduledFuture f = 201 p.scheduleWithFixedDelay(task, timeoutMillis(), 202 LONG_DELAY_MS, MILLISECONDS); 203 await(done); 204 assertTrue(millisElapsedSince(startTime) >= timeoutMillis()); 205 f.cancel(true); 206 } finally { 207 joinPool(p); 208 } 209 } 210 211 static class RunnableCounter implements Runnable { 212 AtomicInteger count = new AtomicInteger(0); 213 public void run() { count.getAndIncrement(); } 214 } 215 216 /** 217 * scheduleAtFixedRate executes series of tasks at given rate 218 */ 219 public void testFixedRateSequence() throws InterruptedException { 220 CustomExecutor p = new CustomExecutor(1); 221 try { 222 for (int delay = 1; delay <= LONG_DELAY_MS; delay *= 3) { 223 long startTime = System.nanoTime(); 224 int cycles = 10; 225 final CountDownLatch done = new CountDownLatch(cycles); 226 Runnable task = new CheckedRunnable() { 227 public void realRun() { done.countDown(); }}; 228 ScheduledFuture h = 229 p.scheduleAtFixedRate(task, 0, delay, MILLISECONDS); 230 done.await(); 231 h.cancel(true); 232 double normalizedTime = 233 (double) millisElapsedSince(startTime) / delay; 234 if (normalizedTime >= cycles - 1 && 235 normalizedTime <= cycles) 236 return; 237 } 238 throw new AssertionError("unexpected execution rate"); 239 } finally { 240 joinPool(p); 241 } 242 } 243 244 /** 245 * scheduleWithFixedDelay executes series of tasks with given period 246 */ 247 public void testFixedDelaySequence() throws InterruptedException { 248 CustomExecutor p = new CustomExecutor(1); 249 try { 250 for (int delay = 1; delay <= LONG_DELAY_MS; delay *= 3) { 251 long startTime = System.nanoTime(); 252 int cycles = 10; 253 final CountDownLatch done = new CountDownLatch(cycles); 254 Runnable task = new CheckedRunnable() { 255 public void realRun() { done.countDown(); }}; 256 ScheduledFuture h = 257 p.scheduleWithFixedDelay(task, 0, delay, MILLISECONDS); 258 done.await(); 259 h.cancel(true); 260 double normalizedTime = 261 (double) millisElapsedSince(startTime) / delay; 262 if (normalizedTime >= cycles - 1 && 263 normalizedTime <= cycles) 264 return; 265 } 266 throw new AssertionError("unexpected execution rate"); 267 } finally { 268 joinPool(p); 269 } 270 } 271 272 /** 273 * execute(null) throws NPE 274 */ 275 public void testExecuteNull() throws InterruptedException { 276 CustomExecutor se = new CustomExecutor(1); 277 try { 278 se.execute(null); 279 shouldThrow(); 280 } catch (NullPointerException success) {} 281 joinPool(se); 282 } 283 284 /** 285 * schedule(null) throws NPE 286 */ 287 public void testScheduleNull() throws InterruptedException { 288 CustomExecutor se = new CustomExecutor(1); 289 try { 290 TrackedCallable callable = null; 291 Future f = se.schedule(callable, SHORT_DELAY_MS, MILLISECONDS); 292 shouldThrow(); 293 } catch (NullPointerException success) {} 294 joinPool(se); 295 } 296 297 /** 298 * execute throws RejectedExecutionException if shutdown 299 */ 300 public void testSchedule1_RejectedExecutionException() { 301 CustomExecutor se = new CustomExecutor(1); 302 try { 303 se.shutdown(); 304 se.schedule(new NoOpRunnable(), 305 MEDIUM_DELAY_MS, MILLISECONDS); 306 shouldThrow(); 307 } catch (RejectedExecutionException success) { 308 } catch (SecurityException ok) { 309 } 310 311 joinPool(se); 312 } 313 314 /** 315 * schedule throws RejectedExecutionException if shutdown 316 */ 317 public void testSchedule2_RejectedExecutionException() { 318 CustomExecutor se = new CustomExecutor(1); 319 try { 320 se.shutdown(); 321 se.schedule(new NoOpCallable(), 322 MEDIUM_DELAY_MS, MILLISECONDS); 323 shouldThrow(); 324 } catch (RejectedExecutionException success) { 325 } catch (SecurityException ok) { 326 } 327 joinPool(se); 328 } 329 330 /** 331 * schedule callable throws RejectedExecutionException if shutdown 332 */ 333 public void testSchedule3_RejectedExecutionException() { 334 CustomExecutor se = new CustomExecutor(1); 335 try { 336 se.shutdown(); 337 se.schedule(new NoOpCallable(), 338 MEDIUM_DELAY_MS, MILLISECONDS); 339 shouldThrow(); 340 } catch (RejectedExecutionException success) { 341 } catch (SecurityException ok) { 342 } 343 joinPool(se); 344 } 345 346 /** 347 * scheduleAtFixedRate throws RejectedExecutionException if shutdown 348 */ 349 public void testScheduleAtFixedRate1_RejectedExecutionException() { 350 CustomExecutor se = new CustomExecutor(1); 351 try { 352 se.shutdown(); 353 se.scheduleAtFixedRate(new NoOpRunnable(), 354 MEDIUM_DELAY_MS, MEDIUM_DELAY_MS, MILLISECONDS); 355 shouldThrow(); 356 } catch (RejectedExecutionException success) { 357 } catch (SecurityException ok) { 358 } 359 joinPool(se); 360 } 361 362 /** 363 * scheduleWithFixedDelay throws RejectedExecutionException if shutdown 364 */ 365 public void testScheduleWithFixedDelay1_RejectedExecutionException() { 366 CustomExecutor se = new CustomExecutor(1); 367 try { 368 se.shutdown(); 369 se.scheduleWithFixedDelay(new NoOpRunnable(), 370 MEDIUM_DELAY_MS, MEDIUM_DELAY_MS, MILLISECONDS); 371 shouldThrow(); 372 } catch (RejectedExecutionException success) { 373 } catch (SecurityException ok) { 374 } 375 joinPool(se); 376 } 377 378 /** 379 * getActiveCount increases but doesn't overestimate, when a 380 * thread becomes active 381 */ 382 public void testGetActiveCount() throws InterruptedException { 383 final ThreadPoolExecutor p = new CustomExecutor(2); 384 final CountDownLatch threadStarted = new CountDownLatch(1); 385 final CountDownLatch done = new CountDownLatch(1); 386 try { 387 assertEquals(0, p.getActiveCount()); 388 p.execute(new CheckedRunnable() { 389 public void realRun() throws InterruptedException { 390 threadStarted.countDown(); 391 assertEquals(1, p.getActiveCount()); 392 done.await(); 393 }}); 394 assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS)); 395 assertEquals(1, p.getActiveCount()); 396 } finally { 397 done.countDown(); 398 joinPool(p); 399 } 400 } 401 402 /** 403 * getCompletedTaskCount increases, but doesn't overestimate, 404 * when tasks complete 405 */ 406 public void testGetCompletedTaskCount() throws InterruptedException { 407 final ThreadPoolExecutor p = new CustomExecutor(2); 408 final CountDownLatch threadStarted = new CountDownLatch(1); 409 final CountDownLatch threadProceed = new CountDownLatch(1); 410 final CountDownLatch threadDone = new CountDownLatch(1); 411 try { 412 assertEquals(0, p.getCompletedTaskCount()); 413 p.execute(new CheckedRunnable() { 414 public void realRun() throws InterruptedException { 415 threadStarted.countDown(); 416 assertEquals(0, p.getCompletedTaskCount()); 417 threadProceed.await(); 418 threadDone.countDown(); 419 }}); 420 await(threadStarted); 421 assertEquals(0, p.getCompletedTaskCount()); 422 threadProceed.countDown(); 423 threadDone.await(); 424 long startTime = System.nanoTime(); 425 while (p.getCompletedTaskCount() != 1) { 426 if (millisElapsedSince(startTime) > LONG_DELAY_MS) 427 fail("timed out"); 428 Thread.yield(); 429 } 430 } finally { 431 joinPool(p); 432 } 433 } 434 435 /** 436 * getCorePoolSize returns size given in constructor if not otherwise set 437 */ 438 public void testGetCorePoolSize() { 439 CustomExecutor p = new CustomExecutor(1); 440 assertEquals(1, p.getCorePoolSize()); 441 joinPool(p); 442 } 443 444 /** 445 * getLargestPoolSize increases, but doesn't overestimate, when 446 * multiple threads active 447 */ 448 public void testGetLargestPoolSize() throws InterruptedException { 449 final int THREADS = 3; 450 final ThreadPoolExecutor p = new CustomExecutor(THREADS); 451 final CountDownLatch threadsStarted = new CountDownLatch(THREADS); 452 final CountDownLatch done = new CountDownLatch(1); 453 try { 454 assertEquals(0, p.getLargestPoolSize()); 455 for (int i = 0; i < THREADS; i++) 456 p.execute(new CheckedRunnable() { 457 public void realRun() throws InterruptedException { 458 threadsStarted.countDown(); 459 done.await(); 460 assertEquals(THREADS, p.getLargestPoolSize()); 461 }}); 462 assertTrue(threadsStarted.await(SMALL_DELAY_MS, MILLISECONDS)); 463 assertEquals(THREADS, p.getLargestPoolSize()); 464 } finally { 465 done.countDown(); 466 joinPool(p); 467 assertEquals(THREADS, p.getLargestPoolSize()); 468 } 469 } 470 471 /** 472 * getPoolSize increases, but doesn't overestimate, when threads 473 * become active 474 */ 475 public void testGetPoolSize() throws InterruptedException { 476 final ThreadPoolExecutor p = new CustomExecutor(1); 477 final CountDownLatch threadStarted = new CountDownLatch(1); 478 final CountDownLatch done = new CountDownLatch(1); 479 try { 480 assertEquals(0, p.getPoolSize()); 481 p.execute(new CheckedRunnable() { 482 public void realRun() throws InterruptedException { 483 threadStarted.countDown(); 484 assertEquals(1, p.getPoolSize()); 485 done.await(); 486 }}); 487 assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS)); 488 assertEquals(1, p.getPoolSize()); 489 } finally { 490 done.countDown(); 491 joinPool(p); 492 } 493 } 494 495 /** 496 * getTaskCount increases, but doesn't overestimate, when tasks 497 * submitted 498 */ 499 public void testGetTaskCount() throws InterruptedException { 500 final ThreadPoolExecutor p = new CustomExecutor(1); 501 final CountDownLatch threadStarted = new CountDownLatch(1); 502 final CountDownLatch done = new CountDownLatch(1); 503 final int TASKS = 5; 504 try { 505 assertEquals(0, p.getTaskCount()); 506 for (int i = 0; i < TASKS; i++) 507 p.execute(new CheckedRunnable() { 508 public void realRun() throws InterruptedException { 509 threadStarted.countDown(); 510 done.await(); 511 }}); 512 assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS)); 513 assertEquals(TASKS, p.getTaskCount()); 514 } finally { 515 done.countDown(); 516 joinPool(p); 517 } 518 } 519 520 /** 521 * getThreadFactory returns factory in constructor if not set 522 */ 523 public void testGetThreadFactory() { 524 ThreadFactory tf = new SimpleThreadFactory(); 525 CustomExecutor p = new CustomExecutor(1, tf); 526 assertSame(tf, p.getThreadFactory()); 527 joinPool(p); 528 } 529 530 /** 531 * setThreadFactory sets the thread factory returned by getThreadFactory 532 */ 533 public void testSetThreadFactory() { 534 ThreadFactory tf = new SimpleThreadFactory(); 535 CustomExecutor p = new CustomExecutor(1); 536 p.setThreadFactory(tf); 537 assertSame(tf, p.getThreadFactory()); 538 joinPool(p); 539 } 540 541 /** 542 * setThreadFactory(null) throws NPE 543 */ 544 public void testSetThreadFactoryNull() { 545 CustomExecutor p = new CustomExecutor(1); 546 try { 547 p.setThreadFactory(null); 548 shouldThrow(); 549 } catch (NullPointerException success) { 550 } finally { 551 joinPool(p); 552 } 553 } 554 555 /** 556 * isShutdown is false before shutdown, true after 557 */ 558 public void testIsShutdown() { 559 CustomExecutor p = new CustomExecutor(1); 560 try { 561 assertFalse(p.isShutdown()); 562 } 563 finally { 564 try { p.shutdown(); } catch (SecurityException ok) { return; } 565 } 566 assertTrue(p.isShutdown()); 567 } 568 569 /** 570 * isTerminated is false before termination, true after 571 */ 572 public void testIsTerminated() throws InterruptedException { 573 final ThreadPoolExecutor p = new CustomExecutor(1); 574 final CountDownLatch threadStarted = new CountDownLatch(1); 575 final CountDownLatch done = new CountDownLatch(1); 576 assertFalse(p.isTerminated()); 577 try { 578 p.execute(new CheckedRunnable() { 579 public void realRun() throws InterruptedException { 580 assertFalse(p.isTerminated()); 581 threadStarted.countDown(); 582 done.await(); 583 }}); 584 assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS)); 585 assertFalse(p.isTerminating()); 586 done.countDown(); 587 } finally { 588 try { p.shutdown(); } catch (SecurityException ok) { return; } 589 } 590 assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS)); 591 assertTrue(p.isTerminated()); 592 } 593 594 /** 595 * isTerminating is not true when running or when terminated 596 */ 597 public void testIsTerminating() throws InterruptedException { 598 final ThreadPoolExecutor p = new CustomExecutor(1); 599 final CountDownLatch threadStarted = new CountDownLatch(1); 600 final CountDownLatch done = new CountDownLatch(1); 601 try { 602 assertFalse(p.isTerminating()); 603 p.execute(new CheckedRunnable() { 604 public void realRun() throws InterruptedException { 605 assertFalse(p.isTerminating()); 606 threadStarted.countDown(); 607 done.await(); 608 }}); 609 assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS)); 610 assertFalse(p.isTerminating()); 611 done.countDown(); 612 } finally { 613 try { p.shutdown(); } catch (SecurityException ok) { return; } 614 } 615 assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS)); 616 assertTrue(p.isTerminated()); 617 assertFalse(p.isTerminating()); 618 } 619 620 /** 621 * getQueue returns the work queue, which contains queued tasks 622 */ 623 public void testGetQueue() throws InterruptedException { 624 ScheduledThreadPoolExecutor p = new CustomExecutor(1); 625 final CountDownLatch threadStarted = new CountDownLatch(1); 626 final CountDownLatch done = new CountDownLatch(1); 627 try { 628 ScheduledFuture[] tasks = new ScheduledFuture[5]; 629 for (int i = 0; i < tasks.length; i++) { 630 Runnable r = new CheckedRunnable() { 631 public void realRun() throws InterruptedException { 632 threadStarted.countDown(); 633 done.await(); 634 }}; 635 tasks[i] = p.schedule(r, 1, MILLISECONDS); 636 } 637 assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS)); 638 BlockingQueue<Runnable> q = p.getQueue(); 639 assertTrue(q.contains(tasks[tasks.length - 1])); 640 assertFalse(q.contains(tasks[0])); 641 } finally { 642 done.countDown(); 643 joinPool(p); 644 } 645 } 646 647 /** 648 * remove(task) removes queued task, and fails to remove active task 649 */ 650 public void testRemove() throws InterruptedException { 651 final ScheduledThreadPoolExecutor p = new CustomExecutor(1); 652 ScheduledFuture[] tasks = new ScheduledFuture[5]; 653 final CountDownLatch threadStarted = new CountDownLatch(1); 654 final CountDownLatch done = new CountDownLatch(1); 655 try { 656 for (int i = 0; i < tasks.length; i++) { 657 Runnable r = new CheckedRunnable() { 658 public void realRun() throws InterruptedException { 659 threadStarted.countDown(); 660 done.await(); 661 }}; 662 tasks[i] = p.schedule(r, 1, MILLISECONDS); 663 } 664 assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS)); 665 BlockingQueue<Runnable> q = p.getQueue(); 666 assertFalse(p.remove((Runnable)tasks[0])); 667 assertTrue(q.contains((Runnable)tasks[4])); 668 assertTrue(q.contains((Runnable)tasks[3])); 669 assertTrue(p.remove((Runnable)tasks[4])); 670 assertFalse(p.remove((Runnable)tasks[4])); 671 assertFalse(q.contains((Runnable)tasks[4])); 672 assertTrue(q.contains((Runnable)tasks[3])); 673 assertTrue(p.remove((Runnable)tasks[3])); 674 assertFalse(q.contains((Runnable)tasks[3])); 675 } finally { 676 done.countDown(); 677 joinPool(p); 678 } 679 } 680 681 /** 682 * purge removes cancelled tasks from the queue 683 */ 684 public void testPurge() throws InterruptedException { 685 CustomExecutor p = new CustomExecutor(1); 686 ScheduledFuture[] tasks = new ScheduledFuture[5]; 687 for (int i = 0; i < tasks.length; i++) 688 tasks[i] = p.schedule(new SmallPossiblyInterruptedRunnable(), 689 LONG_DELAY_MS, MILLISECONDS); 690 try { 691 int max = tasks.length; 692 if (tasks[4].cancel(true)) --max; 693 if (tasks[3].cancel(true)) --max; 694 // There must eventually be an interference-free point at 695 // which purge will not fail. (At worst, when queue is empty.) 696 long startTime = System.nanoTime(); 697 do { 698 p.purge(); 699 long count = p.getTaskCount(); 700 if (count == max) 701 return; 702 } while (millisElapsedSince(startTime) < MEDIUM_DELAY_MS); 703 fail("Purge failed to remove cancelled tasks"); 704 } finally { 705 for (ScheduledFuture task : tasks) 706 task.cancel(true); 707 joinPool(p); 708 } 709 } 710 711 /** 712 * shutdownNow returns a list containing tasks that were not run 713 */ 714 public void testShutdownNow() { 715 CustomExecutor p = new CustomExecutor(1); 716 for (int i = 0; i < 5; i++) 717 p.schedule(new SmallPossiblyInterruptedRunnable(), 718 LONG_DELAY_MS, MILLISECONDS); 719 try { 720 List<Runnable> l = p.shutdownNow(); 721 assertTrue(p.isShutdown()); 722 assertEquals(5, l.size()); 723 } catch (SecurityException ok) { 724 // Allowed in case test doesn't have privs 725 } finally { 726 joinPool(p); 727 } 728 } 729 730 /** 731 * In default setting, shutdown cancels periodic but not delayed 732 * tasks at shutdown 733 */ 734 public void testShutdown1() throws InterruptedException { 735 CustomExecutor p = new CustomExecutor(1); 736 assertTrue(p.getExecuteExistingDelayedTasksAfterShutdownPolicy()); 737 assertFalse(p.getContinueExistingPeriodicTasksAfterShutdownPolicy()); 738 739 ScheduledFuture[] tasks = new ScheduledFuture[5]; 740 for (int i = 0; i < tasks.length; i++) 741 tasks[i] = p.schedule(new NoOpRunnable(), 742 SHORT_DELAY_MS, MILLISECONDS); 743 try { p.shutdown(); } catch (SecurityException ok) { return; } 744 BlockingQueue<Runnable> q = p.getQueue(); 745 for (ScheduledFuture task : tasks) { 746 assertFalse(task.isDone()); 747 assertFalse(task.isCancelled()); 748 assertTrue(q.contains(task)); 749 } 750 assertTrue(p.isShutdown()); 751 assertTrue(p.awaitTermination(SMALL_DELAY_MS, MILLISECONDS)); 752 assertTrue(p.isTerminated()); 753 for (ScheduledFuture task : tasks) { 754 assertTrue(task.isDone()); 755 assertFalse(task.isCancelled()); 756 } 757 } 758 759 /** 760 * If setExecuteExistingDelayedTasksAfterShutdownPolicy is false, 761 * delayed tasks are cancelled at shutdown 762 */ 763 public void testShutdown2() throws InterruptedException { 764 CustomExecutor p = new CustomExecutor(1); 765 p.setExecuteExistingDelayedTasksAfterShutdownPolicy(false); 766 assertFalse(p.getExecuteExistingDelayedTasksAfterShutdownPolicy()); 767 assertFalse(p.getContinueExistingPeriodicTasksAfterShutdownPolicy()); 768 ScheduledFuture[] tasks = new ScheduledFuture[5]; 769 for (int i = 0; i < tasks.length; i++) 770 tasks[i] = p.schedule(new NoOpRunnable(), 771 SHORT_DELAY_MS, MILLISECONDS); 772 BlockingQueue q = p.getQueue(); 773 assertEquals(tasks.length, q.size()); 774 try { p.shutdown(); } catch (SecurityException ok) { return; } 775 assertTrue(p.isShutdown()); 776 assertTrue(q.isEmpty()); 777 assertTrue(p.awaitTermination(SMALL_DELAY_MS, MILLISECONDS)); 778 assertTrue(p.isTerminated()); 779 for (ScheduledFuture task : tasks) { 780 assertTrue(task.isDone()); 781 assertTrue(task.isCancelled()); 782 } 783 } 784 785 /** 786 * If setContinueExistingPeriodicTasksAfterShutdownPolicy is set false, 787 * periodic tasks are cancelled at shutdown 788 */ 789 public void testShutdown3() throws InterruptedException { 790 CustomExecutor p = new CustomExecutor(1); 791 assertTrue(p.getExecuteExistingDelayedTasksAfterShutdownPolicy()); 792 assertFalse(p.getContinueExistingPeriodicTasksAfterShutdownPolicy()); 793 p.setContinueExistingPeriodicTasksAfterShutdownPolicy(false); 794 assertTrue(p.getExecuteExistingDelayedTasksAfterShutdownPolicy()); 795 assertFalse(p.getContinueExistingPeriodicTasksAfterShutdownPolicy()); 796 long initialDelay = LONG_DELAY_MS; 797 ScheduledFuture task = 798 p.scheduleAtFixedRate(new NoOpRunnable(), initialDelay, 799 5, MILLISECONDS); 800 try { p.shutdown(); } catch (SecurityException ok) { return; } 801 assertTrue(p.isShutdown()); 802 assertTrue(p.getQueue().isEmpty()); 803 assertTrue(task.isDone()); 804 assertTrue(task.isCancelled()); 805 joinPool(p); 806 } 807 808 /** 809 * if setContinueExistingPeriodicTasksAfterShutdownPolicy is true, 810 * periodic tasks are not cancelled at shutdown 811 */ 812 public void testShutdown4() throws InterruptedException { 813 CustomExecutor p = new CustomExecutor(1); 814 final CountDownLatch counter = new CountDownLatch(2); 815 try { 816 p.setContinueExistingPeriodicTasksAfterShutdownPolicy(true); 817 assertTrue(p.getExecuteExistingDelayedTasksAfterShutdownPolicy()); 818 assertTrue(p.getContinueExistingPeriodicTasksAfterShutdownPolicy()); 819 final Runnable r = new CheckedRunnable() { 820 public void realRun() { 821 counter.countDown(); 822 }}; 823 ScheduledFuture task = 824 p.scheduleAtFixedRate(r, 1, 1, MILLISECONDS); 825 assertFalse(task.isDone()); 826 assertFalse(task.isCancelled()); 827 try { p.shutdown(); } catch (SecurityException ok) { return; } 828 assertFalse(task.isCancelled()); 829 assertFalse(p.isTerminated()); 830 assertTrue(p.isShutdown()); 831 assertTrue(counter.await(SMALL_DELAY_MS, MILLISECONDS)); 832 assertFalse(task.isCancelled()); 833 assertTrue(task.cancel(false)); 834 assertTrue(task.isDone()); 835 assertTrue(task.isCancelled()); 836 assertTrue(p.awaitTermination(SMALL_DELAY_MS, MILLISECONDS)); 837 assertTrue(p.isTerminated()); 838 } 839 finally { 840 joinPool(p); 841 } 842 } 843 844 /** 845 * completed submit of callable returns result 846 */ 847 public void testSubmitCallable() throws Exception { 848 ExecutorService e = new CustomExecutor(2); 849 try { 850 Future<String> future = e.submit(new StringTask()); 851 String result = future.get(); 852 assertSame(TEST_STRING, result); 853 } finally { 854 joinPool(e); 855 } 856 } 857 858 /** 859 * completed submit of runnable returns successfully 860 */ 861 public void testSubmitRunnable() throws Exception { 862 ExecutorService e = new CustomExecutor(2); 863 try { 864 Future<?> future = e.submit(new NoOpRunnable()); 865 future.get(); 866 assertTrue(future.isDone()); 867 } finally { 868 joinPool(e); 869 } 870 } 871 872 /** 873 * completed submit of (runnable, result) returns result 874 */ 875 public void testSubmitRunnable2() throws Exception { 876 ExecutorService e = new CustomExecutor(2); 877 try { 878 Future<String> future = e.submit(new NoOpRunnable(), TEST_STRING); 879 String result = future.get(); 880 assertSame(TEST_STRING, result); 881 } finally { 882 joinPool(e); 883 } 884 } 885 886 /** 887 * invokeAny(null) throws NPE 888 */ 889 public void testInvokeAny1() throws Exception { 890 ExecutorService e = new CustomExecutor(2); 891 try { 892 e.invokeAny(null); 893 shouldThrow(); 894 } catch (NullPointerException success) { 895 } finally { 896 joinPool(e); 897 } 898 } 899 900 /** 901 * invokeAny(empty collection) throws IAE 902 */ 903 public void testInvokeAny2() throws Exception { 904 ExecutorService e = new CustomExecutor(2); 905 try { 906 e.invokeAny(new ArrayList<Callable<String>>()); 907 shouldThrow(); 908 } catch (IllegalArgumentException success) { 909 } finally { 910 joinPool(e); 911 } 912 } 913 914 /** 915 * invokeAny(c) throws NPE if c has null elements 916 */ 917 public void testInvokeAny3() throws Exception { 918 CountDownLatch latch = new CountDownLatch(1); 919 ExecutorService e = new CustomExecutor(2); 920 List<Callable<String>> l = new ArrayList<Callable<String>>(); 921 l.add(latchAwaitingStringTask(latch)); 922 l.add(null); 923 try { 924 e.invokeAny(l); 925 shouldThrow(); 926 } catch (NullPointerException success) { 927 } finally { 928 latch.countDown(); 929 joinPool(e); 930 } 931 } 932 933 /** 934 * invokeAny(c) throws ExecutionException if no task completes 935 */ 936 public void testInvokeAny4() throws Exception { 937 ExecutorService e = new CustomExecutor(2); 938 List<Callable<String>> l = new ArrayList<Callable<String>>(); 939 l.add(new NPETask()); 940 try { 941 e.invokeAny(l); 942 shouldThrow(); 943 } catch (ExecutionException success) { 944 assertTrue(success.getCause() instanceof NullPointerException); 945 } finally { 946 joinPool(e); 947 } 948 } 949 950 /** 951 * invokeAny(c) returns result of some task 952 */ 953 public void testInvokeAny5() throws Exception { 954 ExecutorService e = new CustomExecutor(2); 955 try { 956 List<Callable<String>> l = new ArrayList<Callable<String>>(); 957 l.add(new StringTask()); 958 l.add(new StringTask()); 959 String result = e.invokeAny(l); 960 assertSame(TEST_STRING, result); 961 } finally { 962 joinPool(e); 963 } 964 } 965 966 /** 967 * invokeAll(null) throws NPE 968 */ 969 public void testInvokeAll1() throws Exception { 970 ExecutorService e = new CustomExecutor(2); 971 try { 972 e.invokeAll(null); 973 shouldThrow(); 974 } catch (NullPointerException success) { 975 } finally { 976 joinPool(e); 977 } 978 } 979 980 /** 981 * invokeAll(empty collection) returns empty collection 982 */ 983 public void testInvokeAll2() throws Exception { 984 ExecutorService e = new CustomExecutor(2); 985 try { 986 List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>()); 987 assertTrue(r.isEmpty()); 988 } finally { 989 joinPool(e); 990 } 991 } 992 993 /** 994 * invokeAll(c) throws NPE if c has null elements 995 */ 996 public void testInvokeAll3() throws Exception { 997 ExecutorService e = new CustomExecutor(2); 998 List<Callable<String>> l = new ArrayList<Callable<String>>(); 999 l.add(new StringTask()); 1000 l.add(null); 1001 try { 1002 e.invokeAll(l); 1003 shouldThrow(); 1004 } catch (NullPointerException success) { 1005 } finally { 1006 joinPool(e); 1007 } 1008 } 1009 1010 /** 1011 * get of invokeAll(c) throws exception on failed task 1012 */ 1013 public void testInvokeAll4() throws Exception { 1014 ExecutorService e = new CustomExecutor(2); 1015 List<Callable<String>> l = new ArrayList<Callable<String>>(); 1016 l.add(new NPETask()); 1017 List<Future<String>> futures = e.invokeAll(l); 1018 assertEquals(1, futures.size()); 1019 try { 1020 futures.get(0).get(); 1021 shouldThrow(); 1022 } catch (ExecutionException success) { 1023 assertTrue(success.getCause() instanceof NullPointerException); 1024 } finally { 1025 joinPool(e); 1026 } 1027 } 1028 1029 /** 1030 * invokeAll(c) returns results of all completed tasks 1031 */ 1032 public void testInvokeAll5() throws Exception { 1033 ExecutorService e = new CustomExecutor(2); 1034 try { 1035 List<Callable<String>> l = new ArrayList<Callable<String>>(); 1036 l.add(new StringTask()); 1037 l.add(new StringTask()); 1038 List<Future<String>> futures = e.invokeAll(l); 1039 assertEquals(2, futures.size()); 1040 for (Future<String> future : futures) 1041 assertSame(TEST_STRING, future.get()); 1042 } finally { 1043 joinPool(e); 1044 } 1045 } 1046 1047 /** 1048 * timed invokeAny(null) throws NPE 1049 */ 1050 public void testTimedInvokeAny1() throws Exception { 1051 ExecutorService e = new CustomExecutor(2); 1052 try { 1053 e.invokeAny(null, MEDIUM_DELAY_MS, MILLISECONDS); 1054 shouldThrow(); 1055 } catch (NullPointerException success) { 1056 } finally { 1057 joinPool(e); 1058 } 1059 } 1060 1061 /** 1062 * timed invokeAny(,,null) throws NPE 1063 */ 1064 public void testTimedInvokeAnyNullTimeUnit() throws Exception { 1065 ExecutorService e = new CustomExecutor(2); 1066 List<Callable<String>> l = new ArrayList<Callable<String>>(); 1067 l.add(new StringTask()); 1068 try { 1069 e.invokeAny(l, MEDIUM_DELAY_MS, null); 1070 shouldThrow(); 1071 } catch (NullPointerException success) { 1072 } finally { 1073 joinPool(e); 1074 } 1075 } 1076 1077 /** 1078 * timed invokeAny(empty collection) throws IAE 1079 */ 1080 public void testTimedInvokeAny2() throws Exception { 1081 ExecutorService e = new CustomExecutor(2); 1082 try { 1083 e.invokeAny(new ArrayList<Callable<String>>(), MEDIUM_DELAY_MS, MILLISECONDS); 1084 shouldThrow(); 1085 } catch (IllegalArgumentException success) { 1086 } finally { 1087 joinPool(e); 1088 } 1089 } 1090 1091 /** 1092 * timed invokeAny(c) throws NPE if c has null elements 1093 */ 1094 public void testTimedInvokeAny3() throws Exception { 1095 CountDownLatch latch = new CountDownLatch(1); 1096 ExecutorService e = new CustomExecutor(2); 1097 List<Callable<String>> l = new ArrayList<Callable<String>>(); 1098 l.add(latchAwaitingStringTask(latch)); 1099 l.add(null); 1100 try { 1101 e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS); 1102 shouldThrow(); 1103 } catch (NullPointerException success) { 1104 } finally { 1105 latch.countDown(); 1106 joinPool(e); 1107 } 1108 } 1109 1110 /** 1111 * timed invokeAny(c) throws ExecutionException if no task completes 1112 */ 1113 public void testTimedInvokeAny4() throws Exception { 1114 ExecutorService e = new CustomExecutor(2); 1115 List<Callable<String>> l = new ArrayList<Callable<String>>(); 1116 l.add(new NPETask()); 1117 try { 1118 e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS); 1119 shouldThrow(); 1120 } catch (ExecutionException success) { 1121 assertTrue(success.getCause() instanceof NullPointerException); 1122 } finally { 1123 joinPool(e); 1124 } 1125 } 1126 1127 /** 1128 * timed invokeAny(c) returns result of some task 1129 */ 1130 public void testTimedInvokeAny5() throws Exception { 1131 ExecutorService e = new CustomExecutor(2); 1132 try { 1133 List<Callable<String>> l = new ArrayList<Callable<String>>(); 1134 l.add(new StringTask()); 1135 l.add(new StringTask()); 1136 String result = e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS); 1137 assertSame(TEST_STRING, result); 1138 } finally { 1139 joinPool(e); 1140 } 1141 } 1142 1143 /** 1144 * timed invokeAll(null) throws NPE 1145 */ 1146 public void testTimedInvokeAll1() throws Exception { 1147 ExecutorService e = new CustomExecutor(2); 1148 try { 1149 e.invokeAll(null, MEDIUM_DELAY_MS, MILLISECONDS); 1150 shouldThrow(); 1151 } catch (NullPointerException success) { 1152 } finally { 1153 joinPool(e); 1154 } 1155 } 1156 1157 /** 1158 * timed invokeAll(,,null) throws NPE 1159 */ 1160 public void testTimedInvokeAllNullTimeUnit() throws Exception { 1161 ExecutorService e = new CustomExecutor(2); 1162 List<Callable<String>> l = new ArrayList<Callable<String>>(); 1163 l.add(new StringTask()); 1164 try { 1165 e.invokeAll(l, MEDIUM_DELAY_MS, null); 1166 shouldThrow(); 1167 } catch (NullPointerException success) { 1168 } finally { 1169 joinPool(e); 1170 } 1171 } 1172 1173 /** 1174 * timed invokeAll(empty collection) returns empty collection 1175 */ 1176 public void testTimedInvokeAll2() throws Exception { 1177 ExecutorService e = new CustomExecutor(2); 1178 try { 1179 List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>(), MEDIUM_DELAY_MS, MILLISECONDS); 1180 assertTrue(r.isEmpty()); 1181 } finally { 1182 joinPool(e); 1183 } 1184 } 1185 1186 /** 1187 * timed invokeAll(c) throws NPE if c has null elements 1188 */ 1189 public void testTimedInvokeAll3() throws Exception { 1190 ExecutorService e = new CustomExecutor(2); 1191 List<Callable<String>> l = new ArrayList<Callable<String>>(); 1192 l.add(new StringTask()); 1193 l.add(null); 1194 try { 1195 e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS); 1196 shouldThrow(); 1197 } catch (NullPointerException success) { 1198 } finally { 1199 joinPool(e); 1200 } 1201 } 1202 1203 /** 1204 * get of element of invokeAll(c) throws exception on failed task 1205 */ 1206 public void testTimedInvokeAll4() throws Exception { 1207 ExecutorService e = new CustomExecutor(2); 1208 List<Callable<String>> l = new ArrayList<Callable<String>>(); 1209 l.add(new NPETask()); 1210 List<Future<String>> futures = 1211 e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS); 1212 assertEquals(1, futures.size()); 1213 try { 1214 futures.get(0).get(); 1215 shouldThrow(); 1216 } catch (ExecutionException success) { 1217 assertTrue(success.getCause() instanceof NullPointerException); 1218 } finally { 1219 joinPool(e); 1220 } 1221 } 1222 1223 /** 1224 * timed invokeAll(c) returns results of all completed tasks 1225 */ 1226 public void testTimedInvokeAll5() throws Exception { 1227 ExecutorService e = new CustomExecutor(2); 1228 try { 1229 List<Callable<String>> l = new ArrayList<Callable<String>>(); 1230 l.add(new StringTask()); 1231 l.add(new StringTask()); 1232 List<Future<String>> futures = 1233 e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS); 1234 assertEquals(2, futures.size()); 1235 for (Future<String> future : futures) 1236 assertSame(TEST_STRING, future.get()); 1237 } finally { 1238 joinPool(e); 1239 } 1240 } 1241 1242 /** 1243 * timed invokeAll(c) cancels tasks not completed by timeout 1244 */ 1245 public void testTimedInvokeAll6() throws Exception { 1246 ExecutorService e = new CustomExecutor(2); 1247 try { 1248 List<Callable<String>> l = new ArrayList<Callable<String>>(); 1249 l.add(new StringTask()); 1250 l.add(Executors.callable(new MediumPossiblyInterruptedRunnable(), TEST_STRING)); 1251 l.add(new StringTask()); 1252 List<Future<String>> futures = 1253 e.invokeAll(l, SHORT_DELAY_MS, MILLISECONDS); 1254 assertEquals(l.size(), futures.size()); 1255 for (Future future : futures) 1256 assertTrue(future.isDone()); 1257 assertFalse(futures.get(0).isCancelled()); 1258 assertTrue(futures.get(1).isCancelled()); 1259 } finally { 1260 joinPool(e); 1261 } 1262 } 1263 1264} 1265