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