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