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 9 package jsr166; 10 11 import static java.util.concurrent.TimeUnit.MILLISECONDS; 12 import static java.util.concurrent.TimeUnit.NANOSECONDS; 13 import static java.util.concurrent.TimeUnit.SECONDS; 14 15 import java.util.ArrayList; 16 import java.util.List; 17 import java.util.concurrent.ArrayBlockingQueue; 18 import java.util.concurrent.BlockingQueue; 19 import java.util.concurrent.Callable; 20 import java.util.concurrent.CancellationException; 21 import java.util.concurrent.CountDownLatch; 22 import java.util.concurrent.ExecutionException; 23 import java.util.concurrent.Executors; 24 import java.util.concurrent.ExecutorService; 25 import java.util.concurrent.Future; 26 import java.util.concurrent.FutureTask; 27 import java.util.concurrent.LinkedBlockingQueue; 28 import java.util.concurrent.RejectedExecutionException; 29 import java.util.concurrent.RejectedExecutionHandler; 30 import java.util.concurrent.SynchronousQueue; 31 import java.util.concurrent.ThreadFactory; 32 import java.util.concurrent.ThreadPoolExecutor; 33 import java.util.concurrent.TimeUnit; 34 import java.util.concurrent.atomic.AtomicInteger; 35 36 import junit.framework.Test; 37 import junit.framework.TestSuite; 38 39 public class ThreadPoolExecutorTest extends JSR166TestCase { 40 // android-note: Removed because the CTS runner does a bad job of 41 // retrying tests that have suite() declarations. 42 // 43 // public static void main(String[] args) { 44 // main(suite(), args); 45 // } 46 // public static Test suite() { 47 // return new TestSuite(ThreadPoolExecutorTest.class); 48 // } 49 50 static class ExtendedTPE extends ThreadPoolExecutor { 51 final CountDownLatch beforeCalled = new CountDownLatch(1); 52 final CountDownLatch afterCalled = new CountDownLatch(1); 53 final CountDownLatch terminatedCalled = new CountDownLatch(1); 54 55 public ExtendedTPE() { 56 super(1, 1, LONG_DELAY_MS, MILLISECONDS, new SynchronousQueue<Runnable>()); 57 } 58 protected void beforeExecute(Thread t, Runnable r) { 59 beforeCalled.countDown(); 60 } 61 protected void afterExecute(Runnable r, Throwable t) { 62 afterCalled.countDown(); 63 } 64 protected void terminated() { 65 terminatedCalled.countDown(); 66 } 67 68 public boolean beforeCalled() { 69 return beforeCalled.getCount() == 0; 70 } 71 public boolean afterCalled() { 72 return afterCalled.getCount() == 0; 73 } 74 public boolean terminatedCalled() { 75 return terminatedCalled.getCount() == 0; 76 } 77 } 78 79 static class FailingThreadFactory implements ThreadFactory { 80 int calls = 0; 81 public Thread newThread(Runnable r) { 82 if (++calls > 1) return null; 83 return new Thread(r); 84 } 85 } 86 87 /** 88 * execute successfully executes a runnable 89 */ 90 public void testExecute() throws InterruptedException { 91 final ThreadPoolExecutor p = 92 new ThreadPoolExecutor(1, 1, 93 LONG_DELAY_MS, MILLISECONDS, 94 new ArrayBlockingQueue<Runnable>(10)); 95 try (PoolCleaner cleaner = cleaner(p)) { 96 final CountDownLatch done = new CountDownLatch(1); 97 final Runnable task = new CheckedRunnable() { 98 public void realRun() { done.countDown(); }}; 99 p.execute(task); 100 assertTrue(done.await(LONG_DELAY_MS, MILLISECONDS)); 101 } 102 } 103 104 /** 105 * getActiveCount increases but doesn't overestimate, when a 106 * thread becomes active 107 */ 108 public void testGetActiveCount() throws InterruptedException { 109 final CountDownLatch done = new CountDownLatch(1); 110 final ThreadPoolExecutor p = 111 new ThreadPoolExecutor(2, 2, 112 LONG_DELAY_MS, MILLISECONDS, 113 new ArrayBlockingQueue<Runnable>(10)); 114 try (PoolCleaner cleaner = cleaner(p, done)) { 115 final CountDownLatch threadStarted = new CountDownLatch(1); 116 assertEquals(0, p.getActiveCount()); 117 p.execute(new CheckedRunnable() { 118 public void realRun() throws InterruptedException { 119 threadStarted.countDown(); 120 assertEquals(1, p.getActiveCount()); 121 await(done); 122 }}); 123 await(threadStarted); 124 assertEquals(1, p.getActiveCount()); 125 } 126 } 127 128 /** 129 * prestartCoreThread starts a thread if under corePoolSize, else doesn't 130 */ 131 public void testPrestartCoreThread() { 132 final ThreadPoolExecutor p = 133 new ThreadPoolExecutor(2, 6, 134 LONG_DELAY_MS, MILLISECONDS, 135 new ArrayBlockingQueue<Runnable>(10)); 136 try (PoolCleaner cleaner = cleaner(p)) { 137 assertEquals(0, p.getPoolSize()); 138 assertTrue(p.prestartCoreThread()); 139 assertEquals(1, p.getPoolSize()); 140 assertTrue(p.prestartCoreThread()); 141 assertEquals(2, p.getPoolSize()); 142 assertFalse(p.prestartCoreThread()); 143 assertEquals(2, p.getPoolSize()); 144 p.setCorePoolSize(4); 145 assertTrue(p.prestartCoreThread()); 146 assertEquals(3, p.getPoolSize()); 147 assertTrue(p.prestartCoreThread()); 148 assertEquals(4, p.getPoolSize()); 149 assertFalse(p.prestartCoreThread()); 150 assertEquals(4, p.getPoolSize()); 151 } 152 } 153 154 /** 155 * prestartAllCoreThreads starts all corePoolSize threads 156 */ 157 public void testPrestartAllCoreThreads() { 158 final ThreadPoolExecutor p = 159 new ThreadPoolExecutor(2, 6, 160 LONG_DELAY_MS, MILLISECONDS, 161 new ArrayBlockingQueue<Runnable>(10)); 162 try (PoolCleaner cleaner = cleaner(p)) { 163 assertEquals(0, p.getPoolSize()); 164 p.prestartAllCoreThreads(); 165 assertEquals(2, p.getPoolSize()); 166 p.prestartAllCoreThreads(); 167 assertEquals(2, p.getPoolSize()); 168 p.setCorePoolSize(4); 169 p.prestartAllCoreThreads(); 170 assertEquals(4, p.getPoolSize()); 171 p.prestartAllCoreThreads(); 172 assertEquals(4, p.getPoolSize()); 173 } 174 } 175 176 /** 177 * getCompletedTaskCount increases, but doesn't overestimate, 178 * when tasks complete 179 */ 180 public void testGetCompletedTaskCount() throws InterruptedException { 181 final ThreadPoolExecutor p = 182 new ThreadPoolExecutor(2, 2, 183 LONG_DELAY_MS, MILLISECONDS, 184 new ArrayBlockingQueue<Runnable>(10)); 185 try (PoolCleaner cleaner = cleaner(p)) { 186 final CountDownLatch threadStarted = new CountDownLatch(1); 187 final CountDownLatch threadProceed = new CountDownLatch(1); 188 final CountDownLatch threadDone = new CountDownLatch(1); 189 assertEquals(0, p.getCompletedTaskCount()); 190 p.execute(new CheckedRunnable() { 191 public void realRun() throws InterruptedException { 192 threadStarted.countDown(); 193 assertEquals(0, p.getCompletedTaskCount()); 194 threadProceed.await(); 195 threadDone.countDown(); 196 }}); 197 await(threadStarted); 198 assertEquals(0, p.getCompletedTaskCount()); 199 threadProceed.countDown(); 200 threadDone.await(); 201 long startTime = System.nanoTime(); 202 while (p.getCompletedTaskCount() != 1) { 203 if (millisElapsedSince(startTime) > LONG_DELAY_MS) 204 fail("timed out"); 205 Thread.yield(); 206 } 207 } 208 } 209 210 /** 211 * getCorePoolSize returns size given in constructor if not otherwise set 212 */ 213 public void testGetCorePoolSize() { 214 final ThreadPoolExecutor p = 215 new ThreadPoolExecutor(1, 1, 216 LONG_DELAY_MS, MILLISECONDS, 217 new ArrayBlockingQueue<Runnable>(10)); 218 try (PoolCleaner cleaner = cleaner(p)) { 219 assertEquals(1, p.getCorePoolSize()); 220 } 221 } 222 223 /** 224 * getKeepAliveTime returns value given in constructor if not otherwise set 225 */ 226 public void testGetKeepAliveTime() { 227 final ThreadPoolExecutor p = 228 new ThreadPoolExecutor(2, 2, 229 1000, MILLISECONDS, 230 new ArrayBlockingQueue<Runnable>(10)); 231 try (PoolCleaner cleaner = cleaner(p)) { 232 assertEquals(1, p.getKeepAliveTime(SECONDS)); 233 } 234 } 235 236 /** 237 * getThreadFactory returns factory in constructor if not set 238 */ 239 public void testGetThreadFactory() { 240 ThreadFactory threadFactory = new SimpleThreadFactory(); 241 final ThreadPoolExecutor p = 242 new ThreadPoolExecutor(1, 2, 243 LONG_DELAY_MS, MILLISECONDS, 244 new ArrayBlockingQueue<Runnable>(10), 245 threadFactory, 246 new NoOpREHandler()); 247 try (PoolCleaner cleaner = cleaner(p)) { 248 assertSame(threadFactory, p.getThreadFactory()); 249 } 250 } 251 252 /** 253 * setThreadFactory sets the thread factory returned by getThreadFactory 254 */ 255 public void testSetThreadFactory() { 256 final ThreadPoolExecutor p = 257 new ThreadPoolExecutor(1, 2, 258 LONG_DELAY_MS, MILLISECONDS, 259 new ArrayBlockingQueue<Runnable>(10)); 260 try (PoolCleaner cleaner = cleaner(p)) { 261 ThreadFactory threadFactory = new SimpleThreadFactory(); 262 p.setThreadFactory(threadFactory); 263 assertSame(threadFactory, p.getThreadFactory()); 264 } 265 } 266 267 /** 268 * setThreadFactory(null) throws NPE 269 */ 270 public void testSetThreadFactoryNull() { 271 final ThreadPoolExecutor p = 272 new ThreadPoolExecutor(1, 2, 273 LONG_DELAY_MS, MILLISECONDS, 274 new ArrayBlockingQueue<Runnable>(10)); 275 try (PoolCleaner cleaner = cleaner(p)) { 276 try { 277 p.setThreadFactory(null); 278 shouldThrow(); 279 } catch (NullPointerException success) {} 280 } 281 } 282 283 /** 284 * getRejectedExecutionHandler returns handler in constructor if not set 285 */ 286 public void testGetRejectedExecutionHandler() { 287 final RejectedExecutionHandler handler = new NoOpREHandler(); 288 final ThreadPoolExecutor p = 289 new ThreadPoolExecutor(1, 2, 290 LONG_DELAY_MS, MILLISECONDS, 291 new ArrayBlockingQueue<Runnable>(10), 292 handler); 293 try (PoolCleaner cleaner = cleaner(p)) { 294 assertSame(handler, p.getRejectedExecutionHandler()); 295 } 296 } 297 298 /** 299 * setRejectedExecutionHandler sets the handler returned by 300 * getRejectedExecutionHandler 301 */ 302 public void testSetRejectedExecutionHandler() { 303 final ThreadPoolExecutor p = 304 new ThreadPoolExecutor(1, 2, 305 LONG_DELAY_MS, MILLISECONDS, 306 new ArrayBlockingQueue<Runnable>(10)); 307 try (PoolCleaner cleaner = cleaner(p)) { 308 RejectedExecutionHandler handler = new NoOpREHandler(); 309 p.setRejectedExecutionHandler(handler); 310 assertSame(handler, p.getRejectedExecutionHandler()); 311 } 312 } 313 314 /** 315 * setRejectedExecutionHandler(null) throws NPE 316 */ 317 public void testSetRejectedExecutionHandlerNull() { 318 final ThreadPoolExecutor p = 319 new ThreadPoolExecutor(1, 2, 320 LONG_DELAY_MS, MILLISECONDS, 321 new ArrayBlockingQueue<Runnable>(10)); 322 try (PoolCleaner cleaner = cleaner(p)) { 323 try { 324 p.setRejectedExecutionHandler(null); 325 shouldThrow(); 326 } catch (NullPointerException success) {} 327 } 328 } 329 330 /** 331 * getLargestPoolSize increases, but doesn't overestimate, when 332 * multiple threads active 333 */ 334 public void testGetLargestPoolSize() throws InterruptedException { 335 final int THREADS = 3; 336 final CountDownLatch done = new CountDownLatch(1); 337 final ThreadPoolExecutor p = 338 new ThreadPoolExecutor(THREADS, THREADS, 339 LONG_DELAY_MS, MILLISECONDS, 340 new ArrayBlockingQueue<Runnable>(10)); 341 try (PoolCleaner cleaner = cleaner(p, done)) { 342 assertEquals(0, p.getLargestPoolSize()); 343 final CountDownLatch threadsStarted = new CountDownLatch(THREADS); 344 for (int i = 0; i < THREADS; i++) 345 p.execute(new CheckedRunnable() { 346 public void realRun() throws InterruptedException { 347 threadsStarted.countDown(); 348 await(done); 349 assertEquals(THREADS, p.getLargestPoolSize()); 350 }}); 351 await(threadsStarted); 352 assertEquals(THREADS, p.getLargestPoolSize()); 353 } 354 assertEquals(THREADS, p.getLargestPoolSize()); 355 } 356 357 /** 358 * getMaximumPoolSize returns value given in constructor if not 359 * otherwise set 360 */ 361 public void testGetMaximumPoolSize() { 362 final ThreadPoolExecutor p = 363 new ThreadPoolExecutor(2, 3, 364 LONG_DELAY_MS, MILLISECONDS, 365 new ArrayBlockingQueue<Runnable>(10)); 366 try (PoolCleaner cleaner = cleaner(p)) { 367 assertEquals(3, p.getMaximumPoolSize()); 368 p.setMaximumPoolSize(5); 369 assertEquals(5, p.getMaximumPoolSize()); 370 p.setMaximumPoolSize(4); 371 assertEquals(4, p.getMaximumPoolSize()); 372 } 373 } 374 375 /** 376 * getPoolSize increases, but doesn't overestimate, when threads 377 * become active 378 */ 379 public void testGetPoolSize() throws InterruptedException { 380 final CountDownLatch done = new CountDownLatch(1); 381 final ThreadPoolExecutor p = 382 new ThreadPoolExecutor(1, 1, 383 LONG_DELAY_MS, MILLISECONDS, 384 new ArrayBlockingQueue<Runnable>(10)); 385 try (PoolCleaner cleaner = cleaner(p, done)) { 386 assertEquals(0, p.getPoolSize()); 387 final CountDownLatch threadStarted = new CountDownLatch(1); 388 p.execute(new CheckedRunnable() { 389 public void realRun() throws InterruptedException { 390 threadStarted.countDown(); 391 assertEquals(1, p.getPoolSize()); 392 await(done); 393 }}); 394 await(threadStarted); 395 assertEquals(1, p.getPoolSize()); 396 } 397 } 398 399 /** 400 * getTaskCount increases, but doesn't overestimate, when tasks submitted 401 */ 402 public void testGetTaskCount() throws InterruptedException { 403 final int TASKS = 3; 404 final CountDownLatch done = new CountDownLatch(1); 405 final ThreadPoolExecutor p = 406 new ThreadPoolExecutor(1, 1, 407 LONG_DELAY_MS, MILLISECONDS, 408 new ArrayBlockingQueue<Runnable>(10)); 409 try (PoolCleaner cleaner = cleaner(p, done)) { 410 final CountDownLatch threadStarted = new CountDownLatch(1); 411 assertEquals(0, p.getTaskCount()); 412 assertEquals(0, p.getCompletedTaskCount()); 413 p.execute(new CheckedRunnable() { 414 public void realRun() throws InterruptedException { 415 threadStarted.countDown(); 416 await(done); 417 }}); 418 await(threadStarted); 419 assertEquals(1, p.getTaskCount()); 420 assertEquals(0, p.getCompletedTaskCount()); 421 for (int i = 0; i < TASKS; i++) { 422 assertEquals(1 + i, p.getTaskCount()); 423 p.execute(new CheckedRunnable() { 424 public void realRun() throws InterruptedException { 425 threadStarted.countDown(); 426 assertEquals(1 + TASKS, p.getTaskCount()); 427 await(done); 428 }}); 429 } 430 assertEquals(1 + TASKS, p.getTaskCount()); 431 assertEquals(0, p.getCompletedTaskCount()); 432 } 433 assertEquals(1 + TASKS, p.getTaskCount()); 434 assertEquals(1 + TASKS, p.getCompletedTaskCount()); 435 } 436 437 /** 438 * isShutdown is false before shutdown, true after 439 */ 440 public void testIsShutdown() { 441 final ThreadPoolExecutor p = 442 new ThreadPoolExecutor(1, 1, 443 LONG_DELAY_MS, MILLISECONDS, 444 new ArrayBlockingQueue<Runnable>(10)); 445 try (PoolCleaner cleaner = cleaner(p)) { 446 assertFalse(p.isShutdown()); 447 try { p.shutdown(); } catch (SecurityException ok) { return; } 448 assertTrue(p.isShutdown()); 449 } 450 } 451 452 /** 453 * awaitTermination on a non-shutdown pool times out 454 */ 455 public void testAwaitTermination_timesOut() throws InterruptedException { 456 final ThreadPoolExecutor p = 457 new ThreadPoolExecutor(1, 1, 458 LONG_DELAY_MS, MILLISECONDS, 459 new ArrayBlockingQueue<Runnable>(10)); 460 try (PoolCleaner cleaner = cleaner(p)) { 461 assertFalse(p.isTerminated()); 462 assertFalse(p.awaitTermination(Long.MIN_VALUE, NANOSECONDS)); 463 assertFalse(p.awaitTermination(Long.MIN_VALUE, MILLISECONDS)); 464 assertFalse(p.awaitTermination(-1L, NANOSECONDS)); 465 assertFalse(p.awaitTermination(-1L, MILLISECONDS)); 466 assertFalse(p.awaitTermination(0L, NANOSECONDS)); 467 assertFalse(p.awaitTermination(0L, MILLISECONDS)); 468 long timeoutNanos = 999999L; 469 long startTime = System.nanoTime(); 470 assertFalse(p.awaitTermination(timeoutNanos, NANOSECONDS)); 471 assertTrue(System.nanoTime() - startTime >= timeoutNanos); 472 assertFalse(p.isTerminated()); 473 startTime = System.nanoTime(); 474 long timeoutMillis = timeoutMillis(); 475 assertFalse(p.awaitTermination(timeoutMillis, MILLISECONDS)); 476 assertTrue(millisElapsedSince(startTime) >= timeoutMillis); 477 assertFalse(p.isTerminated()); 478 try { p.shutdown(); } catch (SecurityException ok) { return; } 479 assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS)); 480 assertTrue(p.isTerminated()); 481 } 482 } 483 484 /** 485 * isTerminated is false before termination, true after 486 */ 487 public void testIsTerminated() throws InterruptedException { 488 final ThreadPoolExecutor p = 489 new ThreadPoolExecutor(1, 1, 490 LONG_DELAY_MS, MILLISECONDS, 491 new ArrayBlockingQueue<Runnable>(10)); 492 try (PoolCleaner cleaner = cleaner(p)) { 493 final CountDownLatch threadStarted = new CountDownLatch(1); 494 final CountDownLatch done = new CountDownLatch(1); 495 assertFalse(p.isTerminating()); 496 p.execute(new CheckedRunnable() { 497 public void realRun() throws InterruptedException { 498 assertFalse(p.isTerminating()); 499 threadStarted.countDown(); 500 await(done); 501 }}); 502 await(threadStarted); 503 assertFalse(p.isTerminating()); 504 done.countDown(); 505 try { p.shutdown(); } catch (SecurityException ok) { return; } 506 assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS)); 507 assertTrue(p.isTerminated()); 508 assertFalse(p.isTerminating()); 509 } 510 } 511 512 /** 513 * isTerminating is not true when running or when terminated 514 */ 515 public void testIsTerminating() throws InterruptedException { 516 final ThreadPoolExecutor p = 517 new ThreadPoolExecutor(1, 1, 518 LONG_DELAY_MS, MILLISECONDS, 519 new ArrayBlockingQueue<Runnable>(10)); 520 try (PoolCleaner cleaner = cleaner(p)) { 521 final CountDownLatch threadStarted = new CountDownLatch(1); 522 final CountDownLatch done = new CountDownLatch(1); 523 assertFalse(p.isTerminating()); 524 p.execute(new CheckedRunnable() { 525 public void realRun() throws InterruptedException { 526 assertFalse(p.isTerminating()); 527 threadStarted.countDown(); 528 await(done); 529 }}); 530 await(threadStarted); 531 assertFalse(p.isTerminating()); 532 done.countDown(); 533 try { p.shutdown(); } catch (SecurityException ok) { return; } 534 assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS)); 535 assertTrue(p.isTerminated()); 536 assertFalse(p.isTerminating()); 537 } 538 } 539 540 /** 541 * getQueue returns the work queue, which contains queued tasks 542 */ 543 public void testGetQueue() throws InterruptedException { 544 final CountDownLatch done = new CountDownLatch(1); 545 final BlockingQueue<Runnable> q = new ArrayBlockingQueue<Runnable>(10); 546 final ThreadPoolExecutor p = 547 new ThreadPoolExecutor(1, 1, 548 LONG_DELAY_MS, MILLISECONDS, 549 q); 550 try (PoolCleaner cleaner = cleaner(p, done)) { 551 final CountDownLatch threadStarted = new CountDownLatch(1); 552 FutureTask[] tasks = new FutureTask[5]; 553 for (int i = 0; i < tasks.length; i++) { 554 Callable task = new CheckedCallable<Boolean>() { 555 public Boolean realCall() throws InterruptedException { 556 threadStarted.countDown(); 557 assertSame(q, p.getQueue()); 558 await(done); 559 return Boolean.TRUE; 560 }}; 561 tasks[i] = new FutureTask(task); 562 p.execute(tasks[i]); 563 } 564 await(threadStarted); 565 assertSame(q, p.getQueue()); 566 assertFalse(q.contains(tasks[0])); 567 assertTrue(q.contains(tasks[tasks.length - 1])); 568 assertEquals(tasks.length - 1, q.size()); 569 } 570 } 571 572 /** 573 * remove(task) removes queued task, and fails to remove active task 574 */ 575 public void testRemove() throws InterruptedException { 576 final CountDownLatch done = new CountDownLatch(1); 577 BlockingQueue<Runnable> q = new ArrayBlockingQueue<Runnable>(10); 578 final ThreadPoolExecutor p = 579 new ThreadPoolExecutor(1, 1, 580 LONG_DELAY_MS, MILLISECONDS, 581 q); 582 try (PoolCleaner cleaner = cleaner(p, done)) { 583 Runnable[] tasks = new Runnable[6]; 584 final CountDownLatch threadStarted = new CountDownLatch(1); 585 for (int i = 0; i < tasks.length; i++) { 586 tasks[i] = new CheckedRunnable() { 587 public void realRun() throws InterruptedException { 588 threadStarted.countDown(); 589 await(done); 590 }}; 591 p.execute(tasks[i]); 592 } 593 await(threadStarted); 594 assertFalse(p.remove(tasks[0])); 595 assertTrue(q.contains(tasks[4])); 596 assertTrue(q.contains(tasks[3])); 597 assertTrue(p.remove(tasks[4])); 598 assertFalse(p.remove(tasks[4])); 599 assertFalse(q.contains(tasks[4])); 600 assertTrue(q.contains(tasks[3])); 601 assertTrue(p.remove(tasks[3])); 602 assertFalse(q.contains(tasks[3])); 603 } 604 } 605 606 /** 607 * purge removes cancelled tasks from the queue 608 */ 609 public void testPurge() throws InterruptedException { 610 final CountDownLatch threadStarted = new CountDownLatch(1); 611 final CountDownLatch done = new CountDownLatch(1); 612 final BlockingQueue<Runnable> q = new ArrayBlockingQueue<Runnable>(10); 613 final ThreadPoolExecutor p = 614 new ThreadPoolExecutor(1, 1, 615 LONG_DELAY_MS, MILLISECONDS, 616 q); 617 try (PoolCleaner cleaner = cleaner(p, done)) { 618 FutureTask[] tasks = new FutureTask[5]; 619 for (int i = 0; i < tasks.length; i++) { 620 Callable task = new CheckedCallable<Boolean>() { 621 public Boolean realCall() throws InterruptedException { 622 threadStarted.countDown(); 623 await(done); 624 return Boolean.TRUE; 625 }}; 626 tasks[i] = new FutureTask(task); 627 p.execute(tasks[i]); 628 } 629 await(threadStarted); 630 assertEquals(tasks.length, p.getTaskCount()); 631 assertEquals(tasks.length - 1, q.size()); 632 assertEquals(1L, p.getActiveCount()); 633 assertEquals(0L, p.getCompletedTaskCount()); 634 tasks[4].cancel(true); 635 tasks[3].cancel(false); 636 p.purge(); 637 assertEquals(tasks.length - 3, q.size()); 638 assertEquals(tasks.length - 2, p.getTaskCount()); 639 p.purge(); // Nothing to do 640 assertEquals(tasks.length - 3, q.size()); 641 assertEquals(tasks.length - 2, p.getTaskCount()); 642 } 643 } 644 645 /** 646 * shutdownNow returns a list containing tasks that were not run, 647 * and those tasks are drained from the queue 648 */ 649 public void testShutdownNow() throws InterruptedException { 650 final int poolSize = 2; 651 final int count = 5; 652 final AtomicInteger ran = new AtomicInteger(0); 653 final ThreadPoolExecutor p = 654 new ThreadPoolExecutor(poolSize, poolSize, 655 LONG_DELAY_MS, MILLISECONDS, 656 new ArrayBlockingQueue<Runnable>(10)); 657 final CountDownLatch threadsStarted = new CountDownLatch(poolSize); 658 Runnable waiter = new CheckedRunnable() { public void realRun() { 659 threadsStarted.countDown(); 660 try { 661 MILLISECONDS.sleep(2 * LONG_DELAY_MS); 662 } catch (InterruptedException success) {} 663 ran.getAndIncrement(); 664 }}; 665 for (int i = 0; i < count; i++) 666 p.execute(waiter); 667 await(threadsStarted); 668 assertEquals(poolSize, p.getActiveCount()); 669 assertEquals(0, p.getCompletedTaskCount()); 670 final List<Runnable> queuedTasks; 671 try { 672 queuedTasks = p.shutdownNow(); 673 } catch (SecurityException ok) { 674 return; // Allowed in case test doesn't have privs 675 } 676 assertTrue(p.isShutdown()); 677 assertTrue(p.getQueue().isEmpty()); 678 assertEquals(count - poolSize, queuedTasks.size()); 679 assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS)); 680 assertTrue(p.isTerminated()); 681 assertEquals(poolSize, ran.get()); 682 assertEquals(poolSize, p.getCompletedTaskCount()); 683 } 684 685 // Exception Tests 686 687 /** 688 * Constructor throws if corePoolSize argument is less than zero 689 */ 690 public void testConstructor1() { 691 try { 692 new ThreadPoolExecutor(-1, 1, 1L, SECONDS, 693 new ArrayBlockingQueue<Runnable>(10)); 694 shouldThrow(); 695 } catch (IllegalArgumentException success) {} 696 } 697 698 /** 699 * Constructor throws if maximumPoolSize is less than zero 700 */ 701 public void testConstructor2() { 702 try { 703 new ThreadPoolExecutor(1, -1, 1L, SECONDS, 704 new ArrayBlockingQueue<Runnable>(10)); 705 shouldThrow(); 706 } catch (IllegalArgumentException success) {} 707 } 708 709 /** 710 * Constructor throws if maximumPoolSize is equal to zero 711 */ 712 public void testConstructor3() { 713 try { 714 new ThreadPoolExecutor(1, 0, 1L, SECONDS, 715 new ArrayBlockingQueue<Runnable>(10)); 716 shouldThrow(); 717 } catch (IllegalArgumentException success) {} 718 } 719 720 /** 721 * Constructor throws if keepAliveTime is less than zero 722 */ 723 public void testConstructor4() { 724 try { 725 new ThreadPoolExecutor(1, 2, -1L, SECONDS, 726 new ArrayBlockingQueue<Runnable>(10)); 727 shouldThrow(); 728 } catch (IllegalArgumentException success) {} 729 } 730 731 /** 732 * Constructor throws if corePoolSize is greater than the maximumPoolSize 733 */ 734 public void testConstructor5() { 735 try { 736 new ThreadPoolExecutor(2, 1, 1L, SECONDS, 737 new ArrayBlockingQueue<Runnable>(10)); 738 shouldThrow(); 739 } catch (IllegalArgumentException success) {} 740 } 741 742 /** 743 * Constructor throws if workQueue is set to null 744 */ 745 public void testConstructorNullPointerException() { 746 try { 747 new ThreadPoolExecutor(1, 2, 1L, SECONDS, 748 (BlockingQueue) null); 749 shouldThrow(); 750 } catch (NullPointerException success) {} 751 } 752 753 /** 754 * Constructor throws if corePoolSize argument is less than zero 755 */ 756 public void testConstructor6() { 757 try { 758 new ThreadPoolExecutor(-1, 1, 1L, SECONDS, 759 new ArrayBlockingQueue<Runnable>(10), 760 new SimpleThreadFactory()); 761 shouldThrow(); 762 } catch (IllegalArgumentException success) {} 763 } 764 765 /** 766 * Constructor throws if maximumPoolSize is less than zero 767 */ 768 public void testConstructor7() { 769 try { 770 new ThreadPoolExecutor(1, -1, 1L, SECONDS, 771 new ArrayBlockingQueue<Runnable>(10), 772 new SimpleThreadFactory()); 773 shouldThrow(); 774 } catch (IllegalArgumentException success) {} 775 } 776 777 /** 778 * Constructor throws if maximumPoolSize is equal to zero 779 */ 780 public void testConstructor8() { 781 try { 782 new ThreadPoolExecutor(1, 0, 1L, SECONDS, 783 new ArrayBlockingQueue<Runnable>(10), 784 new SimpleThreadFactory()); 785 shouldThrow(); 786 } catch (IllegalArgumentException success) {} 787 } 788 789 /** 790 * Constructor throws if keepAliveTime is less than zero 791 */ 792 public void testConstructor9() { 793 try { 794 new ThreadPoolExecutor(1, 2, -1L, SECONDS, 795 new ArrayBlockingQueue<Runnable>(10), 796 new SimpleThreadFactory()); 797 shouldThrow(); 798 } catch (IllegalArgumentException success) {} 799 } 800 801 /** 802 * Constructor throws if corePoolSize is greater than the maximumPoolSize 803 */ 804 public void testConstructor10() { 805 try { 806 new ThreadPoolExecutor(2, 1, 1L, SECONDS, 807 new ArrayBlockingQueue<Runnable>(10), 808 new SimpleThreadFactory()); 809 shouldThrow(); 810 } catch (IllegalArgumentException success) {} 811 } 812 813 /** 814 * Constructor throws if workQueue is set to null 815 */ 816 public void testConstructorNullPointerException2() { 817 try { 818 new ThreadPoolExecutor(1, 2, 1L, SECONDS, 819 (BlockingQueue) null, 820 new SimpleThreadFactory()); 821 shouldThrow(); 822 } catch (NullPointerException success) {} 823 } 824 825 /** 826 * Constructor throws if threadFactory is set to null 827 */ 828 public void testConstructorNullPointerException3() { 829 try { 830 new ThreadPoolExecutor(1, 2, 1L, SECONDS, 831 new ArrayBlockingQueue<Runnable>(10), 832 (ThreadFactory) null); 833 shouldThrow(); 834 } catch (NullPointerException success) {} 835 } 836 837 /** 838 * Constructor throws if corePoolSize argument is less than zero 839 */ 840 public void testConstructor11() { 841 try { 842 new ThreadPoolExecutor(-1, 1, 1L, SECONDS, 843 new ArrayBlockingQueue<Runnable>(10), 844 new NoOpREHandler()); 845 shouldThrow(); 846 } catch (IllegalArgumentException success) {} 847 } 848 849 /** 850 * Constructor throws if maximumPoolSize is less than zero 851 */ 852 public void testConstructor12() { 853 try { 854 new ThreadPoolExecutor(1, -1, 1L, SECONDS, 855 new ArrayBlockingQueue<Runnable>(10), 856 new NoOpREHandler()); 857 shouldThrow(); 858 } catch (IllegalArgumentException success) {} 859 } 860 861 /** 862 * Constructor throws if maximumPoolSize is equal to zero 863 */ 864 public void testConstructor13() { 865 try { 866 new ThreadPoolExecutor(1, 0, 1L, SECONDS, 867 new ArrayBlockingQueue<Runnable>(10), 868 new NoOpREHandler()); 869 shouldThrow(); 870 } catch (IllegalArgumentException success) {} 871 } 872 873 /** 874 * Constructor throws if keepAliveTime is less than zero 875 */ 876 public void testConstructor14() { 877 try { 878 new ThreadPoolExecutor(1, 2, -1L, SECONDS, 879 new ArrayBlockingQueue<Runnable>(10), 880 new NoOpREHandler()); 881 shouldThrow(); 882 } catch (IllegalArgumentException success) {} 883 } 884 885 /** 886 * Constructor throws if corePoolSize is greater than the maximumPoolSize 887 */ 888 public void testConstructor15() { 889 try { 890 new ThreadPoolExecutor(2, 1, 1L, SECONDS, 891 new ArrayBlockingQueue<Runnable>(10), 892 new NoOpREHandler()); 893 shouldThrow(); 894 } catch (IllegalArgumentException success) {} 895 } 896 897 /** 898 * Constructor throws if workQueue is set to null 899 */ 900 public void testConstructorNullPointerException4() { 901 try { 902 new ThreadPoolExecutor(1, 2, 1L, SECONDS, 903 (BlockingQueue) null, 904 new NoOpREHandler()); 905 shouldThrow(); 906 } catch (NullPointerException success) {} 907 } 908 909 /** 910 * Constructor throws if handler is set to null 911 */ 912 public void testConstructorNullPointerException5() { 913 try { 914 new ThreadPoolExecutor(1, 2, 1L, SECONDS, 915 new ArrayBlockingQueue<Runnable>(10), 916 (RejectedExecutionHandler) null); 917 shouldThrow(); 918 } catch (NullPointerException success) {} 919 } 920 921 /** 922 * Constructor throws if corePoolSize argument is less than zero 923 */ 924 public void testConstructor16() { 925 try { 926 new ThreadPoolExecutor(-1, 1, 1L, SECONDS, 927 new ArrayBlockingQueue<Runnable>(10), 928 new SimpleThreadFactory(), 929 new NoOpREHandler()); 930 shouldThrow(); 931 } catch (IllegalArgumentException success) {} 932 } 933 934 /** 935 * Constructor throws if maximumPoolSize is less than zero 936 */ 937 public void testConstructor17() { 938 try { 939 new ThreadPoolExecutor(1, -1, 1L, SECONDS, 940 new ArrayBlockingQueue<Runnable>(10), 941 new SimpleThreadFactory(), 942 new NoOpREHandler()); 943 shouldThrow(); 944 } catch (IllegalArgumentException success) {} 945 } 946 947 /** 948 * Constructor throws if maximumPoolSize is equal to zero 949 */ 950 public void testConstructor18() { 951 try { 952 new ThreadPoolExecutor(1, 0, 1L, SECONDS, 953 new ArrayBlockingQueue<Runnable>(10), 954 new SimpleThreadFactory(), 955 new NoOpREHandler()); 956 shouldThrow(); 957 } catch (IllegalArgumentException success) {} 958 } 959 960 /** 961 * Constructor throws if keepAliveTime is less than zero 962 */ 963 public void testConstructor19() { 964 try { 965 new ThreadPoolExecutor(1, 2, -1L, SECONDS, 966 new ArrayBlockingQueue<Runnable>(10), 967 new SimpleThreadFactory(), 968 new NoOpREHandler()); 969 shouldThrow(); 970 } catch (IllegalArgumentException success) {} 971 } 972 973 /** 974 * Constructor throws if corePoolSize is greater than the maximumPoolSize 975 */ 976 public void testConstructor20() { 977 try { 978 new ThreadPoolExecutor(2, 1, 1L, SECONDS, 979 new ArrayBlockingQueue<Runnable>(10), 980 new SimpleThreadFactory(), 981 new NoOpREHandler()); 982 shouldThrow(); 983 } catch (IllegalArgumentException success) {} 984 } 985 986 /** 987 * Constructor throws if workQueue is null 988 */ 989 public void testConstructorNullPointerException6() { 990 try { 991 new ThreadPoolExecutor(1, 2, 1L, SECONDS, 992 (BlockingQueue) null, 993 new SimpleThreadFactory(), 994 new NoOpREHandler()); 995 shouldThrow(); 996 } catch (NullPointerException success) {} 997 } 998 999 /** 1000 * Constructor throws if handler is null 1001 */ 1002 public void testConstructorNullPointerException7() { 1003 try { 1004 new ThreadPoolExecutor(1, 2, 1L, SECONDS, 1005 new ArrayBlockingQueue<Runnable>(10), 1006 new SimpleThreadFactory(), 1007 (RejectedExecutionHandler) null); 1008 shouldThrow(); 1009 } catch (NullPointerException success) {} 1010 } 1011 1012 /** 1013 * Constructor throws if ThreadFactory is null 1014 */ 1015 public void testConstructorNullPointerException8() { 1016 try { 1017 new ThreadPoolExecutor(1, 2, 1L, SECONDS, 1018 new ArrayBlockingQueue<Runnable>(10), 1019 (ThreadFactory) null, 1020 new NoOpREHandler()); 1021 shouldThrow(); 1022 } catch (NullPointerException success) {} 1023 } 1024 1025 /** 1026 * get of submitted callable throws InterruptedException if interrupted 1027 */ 1028 public void testInterruptedSubmit() throws InterruptedException { 1029 final CountDownLatch done = new CountDownLatch(1); 1030 final ThreadPoolExecutor p = 1031 new ThreadPoolExecutor(1, 1, 1032 60, SECONDS, 1033 new ArrayBlockingQueue<Runnable>(10)); 1034 1035 try (PoolCleaner cleaner = cleaner(p, done)) { 1036 final CountDownLatch threadStarted = new CountDownLatch(1); 1037 Thread t = newStartedThread(new CheckedInterruptedRunnable() { 1038 public void realRun() throws Exception { 1039 Callable task = new CheckedCallable<Boolean>() { 1040 public Boolean realCall() throws InterruptedException { 1041 threadStarted.countDown(); 1042 await(done); 1043 return Boolean.TRUE; 1044 }}; 1045 p.submit(task).get(); 1046 }}); 1047 1048 await(threadStarted); 1049 t.interrupt(); 1050 awaitTermination(t); 1051 } 1052 } 1053 1054 /** 1055 * execute throws RejectedExecutionException if saturated. 1056 */ 1057 public void testSaturatedExecute() { 1058 final CountDownLatch done = new CountDownLatch(1); 1059 final ThreadPoolExecutor p = 1060 new ThreadPoolExecutor(1, 1, 1061 LONG_DELAY_MS, MILLISECONDS, 1062 new ArrayBlockingQueue<Runnable>(1)); 1063 try (PoolCleaner cleaner = cleaner(p, done)) { 1064 Runnable task = new CheckedRunnable() { 1065 public void realRun() throws InterruptedException { 1066 await(done); 1067 }}; 1068 for (int i = 0; i < 2; ++i) 1069 p.execute(task); 1070 for (int i = 0; i < 2; ++i) { 1071 try { 1072 p.execute(task); 1073 shouldThrow(); 1074 } catch (RejectedExecutionException success) {} 1075 assertTrue(p.getTaskCount() <= 2); 1076 } 1077 } 1078 } 1079 1080 /** 1081 * submit(runnable) throws RejectedExecutionException if saturated. 1082 */ 1083 public void testSaturatedSubmitRunnable() { 1084 final CountDownLatch done = new CountDownLatch(1); 1085 final ThreadPoolExecutor p = 1086 new ThreadPoolExecutor(1, 1, 1087 LONG_DELAY_MS, MILLISECONDS, 1088 new ArrayBlockingQueue<Runnable>(1)); 1089 try (PoolCleaner cleaner = cleaner(p, done)) { 1090 Runnable task = new CheckedRunnable() { 1091 public void realRun() throws InterruptedException { 1092 await(done); 1093 }}; 1094 for (int i = 0; i < 2; ++i) 1095 p.submit(task); 1096 for (int i = 0; i < 2; ++i) { 1097 try { 1098 p.execute(task); 1099 shouldThrow(); 1100 } catch (RejectedExecutionException success) {} 1101 assertTrue(p.getTaskCount() <= 2); 1102 } 1103 } 1104 } 1105 1106 /** 1107 * submit(callable) throws RejectedExecutionException if saturated. 1108 */ 1109 public void testSaturatedSubmitCallable() { 1110 final CountDownLatch done = new CountDownLatch(1); 1111 final ThreadPoolExecutor p = 1112 new ThreadPoolExecutor(1, 1, 1113 LONG_DELAY_MS, MILLISECONDS, 1114 new ArrayBlockingQueue<Runnable>(1)); 1115 try (PoolCleaner cleaner = cleaner(p, done)) { 1116 Runnable task = new CheckedRunnable() { 1117 public void realRun() throws InterruptedException { 1118 await(done); 1119 }}; 1120 for (int i = 0; i < 2; ++i) 1121 p.submit(Executors.callable(task)); 1122 for (int i = 0; i < 2; ++i) { 1123 try { 1124 p.execute(task); 1125 shouldThrow(); 1126 } catch (RejectedExecutionException success) {} 1127 assertTrue(p.getTaskCount() <= 2); 1128 } 1129 } 1130 } 1131 1132 /** 1133 * executor using CallerRunsPolicy runs task if saturated. 1134 */ 1135 public void testSaturatedExecute2() { 1136 final ThreadPoolExecutor p = 1137 new ThreadPoolExecutor(1, 1, 1138 LONG_DELAY_MS, 1139 MILLISECONDS, 1140 new ArrayBlockingQueue<Runnable>(1), 1141 new ThreadPoolExecutor.CallerRunsPolicy()); 1142 try (PoolCleaner cleaner = cleaner(p)) { 1143 final CountDownLatch done = new CountDownLatch(1); 1144 Runnable blocker = new CheckedRunnable() { 1145 public void realRun() throws InterruptedException { 1146 await(done); 1147 }}; 1148 p.execute(blocker); 1149 TrackedNoOpRunnable[] tasks = new TrackedNoOpRunnable[5]; 1150 for (int i = 0; i < tasks.length; i++) 1151 tasks[i] = new TrackedNoOpRunnable(); 1152 for (int i = 0; i < tasks.length; i++) 1153 p.execute(tasks[i]); 1154 for (int i = 1; i < tasks.length; i++) 1155 assertTrue(tasks[i].done); 1156 assertFalse(tasks[0].done); // waiting in queue 1157 done.countDown(); 1158 } 1159 } 1160 1161 /** 1162 * executor using DiscardPolicy drops task if saturated. 1163 */ 1164 public void testSaturatedExecute3() { 1165 final CountDownLatch done = new CountDownLatch(1); 1166 final TrackedNoOpRunnable[] tasks = new TrackedNoOpRunnable[5]; 1167 for (int i = 0; i < tasks.length; ++i) 1168 tasks[i] = new TrackedNoOpRunnable(); 1169 final ThreadPoolExecutor p = 1170 new ThreadPoolExecutor(1, 1, 1171 LONG_DELAY_MS, MILLISECONDS, 1172 new ArrayBlockingQueue<Runnable>(1), 1173 new ThreadPoolExecutor.DiscardPolicy()); 1174 try (PoolCleaner cleaner = cleaner(p, done)) { 1175 p.execute(awaiter(done)); 1176 1177 for (TrackedNoOpRunnable task : tasks) 1178 p.execute(task); 1179 for (int i = 1; i < tasks.length; i++) 1180 assertFalse(tasks[i].done); 1181 } 1182 for (int i = 1; i < tasks.length; i++) 1183 assertFalse(tasks[i].done); 1184 assertTrue(tasks[0].done); // was waiting in queue 1185 } 1186 1187 /** 1188 * executor using DiscardOldestPolicy drops oldest task if saturated. 1189 */ 1190 public void testSaturatedExecute4() { 1191 final CountDownLatch done = new CountDownLatch(1); 1192 LatchAwaiter r1 = awaiter(done); 1193 LatchAwaiter r2 = awaiter(done); 1194 LatchAwaiter r3 = awaiter(done); 1195 final ThreadPoolExecutor p = 1196 new ThreadPoolExecutor(1, 1, 1197 LONG_DELAY_MS, MILLISECONDS, 1198 new ArrayBlockingQueue<Runnable>(1), 1199 new ThreadPoolExecutor.DiscardOldestPolicy()); 1200 try (PoolCleaner cleaner = cleaner(p, done)) { 1201 assertEquals(LatchAwaiter.NEW, r1.state); 1202 assertEquals(LatchAwaiter.NEW, r2.state); 1203 assertEquals(LatchAwaiter.NEW, r3.state); 1204 p.execute(r1); 1205 p.execute(r2); 1206 assertTrue(p.getQueue().contains(r2)); 1207 p.execute(r3); 1208 assertFalse(p.getQueue().contains(r2)); 1209 assertTrue(p.getQueue().contains(r3)); 1210 } 1211 assertEquals(LatchAwaiter.DONE, r1.state); 1212 assertEquals(LatchAwaiter.NEW, r2.state); 1213 assertEquals(LatchAwaiter.DONE, r3.state); 1214 } 1215 1216 /** 1217 * execute throws RejectedExecutionException if shutdown 1218 */ 1219 public void testRejectedExecutionExceptionOnShutdown() { 1220 final ThreadPoolExecutor p = 1221 new ThreadPoolExecutor(1, 1, 1222 LONG_DELAY_MS, MILLISECONDS, 1223 new ArrayBlockingQueue<Runnable>(1)); 1224 try { p.shutdown(); } catch (SecurityException ok) { return; } 1225 try (PoolCleaner cleaner = cleaner(p)) { 1226 try { 1227 p.execute(new NoOpRunnable()); 1228 shouldThrow(); 1229 } catch (RejectedExecutionException success) {} 1230 } 1231 } 1232 1233 /** 1234 * execute using CallerRunsPolicy drops task on shutdown 1235 */ 1236 public void testCallerRunsOnShutdown() { 1237 RejectedExecutionHandler h = new ThreadPoolExecutor.CallerRunsPolicy(); 1238 final ThreadPoolExecutor p = 1239 new ThreadPoolExecutor(1, 1, 1240 LONG_DELAY_MS, MILLISECONDS, 1241 new ArrayBlockingQueue<Runnable>(1), h); 1242 1243 try { p.shutdown(); } catch (SecurityException ok) { return; } 1244 try (PoolCleaner cleaner = cleaner(p)) { 1245 TrackedNoOpRunnable r = new TrackedNoOpRunnable(); 1246 p.execute(r); 1247 assertFalse(r.done); 1248 } 1249 } 1250 1251 /** 1252 * execute using DiscardPolicy drops task on shutdown 1253 */ 1254 public void testDiscardOnShutdown() { 1255 final ThreadPoolExecutor p = 1256 new ThreadPoolExecutor(1, 1, 1257 LONG_DELAY_MS, MILLISECONDS, 1258 new ArrayBlockingQueue<Runnable>(1), 1259 new ThreadPoolExecutor.DiscardPolicy()); 1260 1261 try { p.shutdown(); } catch (SecurityException ok) { return; } 1262 try (PoolCleaner cleaner = cleaner(p)) { 1263 TrackedNoOpRunnable r = new TrackedNoOpRunnable(); 1264 p.execute(r); 1265 assertFalse(r.done); 1266 } 1267 } 1268 1269 /** 1270 * execute using DiscardOldestPolicy drops task on shutdown 1271 */ 1272 public void testDiscardOldestOnShutdown() { 1273 final ThreadPoolExecutor p = 1274 new ThreadPoolExecutor(1, 1, 1275 LONG_DELAY_MS, MILLISECONDS, 1276 new ArrayBlockingQueue<Runnable>(1), 1277 new ThreadPoolExecutor.DiscardOldestPolicy()); 1278 1279 try { p.shutdown(); } catch (SecurityException ok) { return; } 1280 try (PoolCleaner cleaner = cleaner(p)) { 1281 TrackedNoOpRunnable r = new TrackedNoOpRunnable(); 1282 p.execute(r); 1283 assertFalse(r.done); 1284 } 1285 } 1286 1287 /** 1288 * execute(null) throws NPE 1289 */ 1290 public void testExecuteNull() { 1291 final ThreadPoolExecutor p = 1292 new ThreadPoolExecutor(1, 2, 1293 1L, SECONDS, 1294 new ArrayBlockingQueue<Runnable>(10)); 1295 try (PoolCleaner cleaner = cleaner(p)) { 1296 try { 1297 p.execute(null); 1298 shouldThrow(); 1299 } catch (NullPointerException success) {} 1300 } 1301 } 1302 1303 /** 1304 * setCorePoolSize of negative value throws IllegalArgumentException 1305 */ 1306 public void testCorePoolSizeIllegalArgumentException() { 1307 final ThreadPoolExecutor p = 1308 new ThreadPoolExecutor(1, 2, 1309 LONG_DELAY_MS, MILLISECONDS, 1310 new ArrayBlockingQueue<Runnable>(10)); 1311 try (PoolCleaner cleaner = cleaner(p)) { 1312 try { 1313 p.setCorePoolSize(-1); 1314 shouldThrow(); 1315 } catch (IllegalArgumentException success) {} 1316 } 1317 } 1318 1319 /** 1320 * setMaximumPoolSize(int) throws IllegalArgumentException if 1321 * given a value less the core pool size 1322 */ 1323 public void testMaximumPoolSizeIllegalArgumentException() { 1324 final ThreadPoolExecutor p = 1325 new ThreadPoolExecutor(2, 3, 1326 LONG_DELAY_MS, MILLISECONDS, 1327 new ArrayBlockingQueue<Runnable>(10)); 1328 try (PoolCleaner cleaner = cleaner(p)) { 1329 try { 1330 p.setMaximumPoolSize(1); 1331 shouldThrow(); 1332 } catch (IllegalArgumentException success) {} 1333 } 1334 } 1335 1336 /** 1337 * setMaximumPoolSize throws IllegalArgumentException 1338 * if given a negative value 1339 */ 1340 public void testMaximumPoolSizeIllegalArgumentException2() { 1341 final ThreadPoolExecutor p = 1342 new ThreadPoolExecutor(2, 3, 1343 LONG_DELAY_MS, MILLISECONDS, 1344 new ArrayBlockingQueue<Runnable>(10)); 1345 try (PoolCleaner cleaner = cleaner(p)) { 1346 try { 1347 p.setMaximumPoolSize(-1); 1348 shouldThrow(); 1349 } catch (IllegalArgumentException success) {} 1350 } 1351 } 1352 1353 /** 1354 * Configuration changes that allow core pool size greater than 1355 * max pool size result in IllegalArgumentException. 1356 */ 1357 public void testPoolSizeInvariants() { 1358 final ThreadPoolExecutor p = 1359 new ThreadPoolExecutor(1, 1, 1360 LONG_DELAY_MS, MILLISECONDS, 1361 new ArrayBlockingQueue<Runnable>(10)); 1362 try (PoolCleaner cleaner = cleaner(p)) { 1363 for (int s = 1; s < 5; s++) { 1364 p.setMaximumPoolSize(s); 1365 p.setCorePoolSize(s); 1366 try { 1367 p.setMaximumPoolSize(s - 1); 1368 shouldThrow(); 1369 } catch (IllegalArgumentException success) {} 1370 assertEquals(s, p.getCorePoolSize()); 1371 assertEquals(s, p.getMaximumPoolSize()); 1372 try { 1373 p.setCorePoolSize(s + 1); 1374 // android-changed: changeset dfec9b5386ca028cc1468f3e2717120ab6274702 1375 // disables this check for compatibility reason. 1376 // shouldThrow(); 1377 } catch (IllegalArgumentException success) {} 1378 // android-changed: changeset dfec9b5386ca028cc1468f3e2717120ab6274702 1379 // disables maximumpoolsize check for compatibility reason. 1380 // assertEquals(s, p.getCorePoolSize()); 1381 assertEquals(s + 1, p.getCorePoolSize()); 1382 assertEquals(s, p.getMaximumPoolSize()); 1383 } 1384 } 1385 } 1386 1387 /** 1388 * setKeepAliveTime throws IllegalArgumentException 1389 * when given a negative value 1390 */ 1391 public void testKeepAliveTimeIllegalArgumentException() { 1392 final ThreadPoolExecutor p = 1393 new ThreadPoolExecutor(2, 3, 1394 LONG_DELAY_MS, MILLISECONDS, 1395 new ArrayBlockingQueue<Runnable>(10)); 1396 try (PoolCleaner cleaner = cleaner(p)) { 1397 try { 1398 p.setKeepAliveTime(-1, MILLISECONDS); 1399 shouldThrow(); 1400 } catch (IllegalArgumentException success) {} 1401 } 1402 } 1403 1404 /** 1405 * terminated() is called on termination 1406 */ 1407 public void testTerminated() { 1408 ExtendedTPE p = new ExtendedTPE(); 1409 try (PoolCleaner cleaner = cleaner(p)) { 1410 try { p.shutdown(); } catch (SecurityException ok) { return; } 1411 assertTrue(p.terminatedCalled()); 1412 assertTrue(p.isShutdown()); 1413 } 1414 } 1415 1416 /** 1417 * beforeExecute and afterExecute are called when executing task 1418 */ 1419 public void testBeforeAfter() throws InterruptedException { 1420 ExtendedTPE p = new ExtendedTPE(); 1421 try (PoolCleaner cleaner = cleaner(p)) { 1422 final CountDownLatch done = new CountDownLatch(1); 1423 p.execute(new CheckedRunnable() { 1424 public void realRun() { 1425 done.countDown(); 1426 }}); 1427 await(p.afterCalled); 1428 assertEquals(0, done.getCount()); 1429 assertTrue(p.afterCalled()); 1430 assertTrue(p.beforeCalled()); 1431 } 1432 } 1433 1434 /** 1435 * completed submit of callable returns result 1436 */ 1437 public void testSubmitCallable() throws Exception { 1438 final ExecutorService e = 1439 new ThreadPoolExecutor(2, 2, 1440 LONG_DELAY_MS, MILLISECONDS, 1441 new ArrayBlockingQueue<Runnable>(10)); 1442 try (PoolCleaner cleaner = cleaner(e)) { 1443 Future<String> future = e.submit(new StringTask()); 1444 String result = future.get(); 1445 assertSame(TEST_STRING, result); 1446 } 1447 } 1448 1449 /** 1450 * completed submit of runnable returns successfully 1451 */ 1452 public void testSubmitRunnable() throws Exception { 1453 final ExecutorService e = 1454 new ThreadPoolExecutor(2, 2, 1455 LONG_DELAY_MS, MILLISECONDS, 1456 new ArrayBlockingQueue<Runnable>(10)); 1457 try (PoolCleaner cleaner = cleaner(e)) { 1458 Future<?> future = e.submit(new NoOpRunnable()); 1459 future.get(); 1460 assertTrue(future.isDone()); 1461 } 1462 } 1463 1464 /** 1465 * completed submit of (runnable, result) returns result 1466 */ 1467 public void testSubmitRunnable2() throws Exception { 1468 final ExecutorService e = 1469 new ThreadPoolExecutor(2, 2, 1470 LONG_DELAY_MS, MILLISECONDS, 1471 new ArrayBlockingQueue<Runnable>(10)); 1472 try (PoolCleaner cleaner = cleaner(e)) { 1473 Future<String> future = e.submit(new NoOpRunnable(), TEST_STRING); 1474 String result = future.get(); 1475 assertSame(TEST_STRING, result); 1476 } 1477 } 1478 1479 /** 1480 * invokeAny(null) throws NPE 1481 */ 1482 public void testInvokeAny1() throws Exception { 1483 final ExecutorService e = 1484 new ThreadPoolExecutor(2, 2, 1485 LONG_DELAY_MS, MILLISECONDS, 1486 new ArrayBlockingQueue<Runnable>(10)); 1487 try (PoolCleaner cleaner = cleaner(e)) { 1488 try { 1489 e.invokeAny(null); 1490 shouldThrow(); 1491 } catch (NullPointerException success) {} 1492 } 1493 } 1494 1495 /** 1496 * invokeAny(empty collection) throws IAE 1497 */ 1498 public void testInvokeAny2() throws Exception { 1499 final ExecutorService e = 1500 new ThreadPoolExecutor(2, 2, 1501 LONG_DELAY_MS, MILLISECONDS, 1502 new ArrayBlockingQueue<Runnable>(10)); 1503 try (PoolCleaner cleaner = cleaner(e)) { 1504 try { 1505 e.invokeAny(new ArrayList<Callable<String>>()); 1506 shouldThrow(); 1507 } catch (IllegalArgumentException success) {} 1508 } 1509 } 1510 1511 /** 1512 * invokeAny(c) throws NPE if c has null elements 1513 */ 1514 public void testInvokeAny3() throws Exception { 1515 final CountDownLatch latch = new CountDownLatch(1); 1516 final ExecutorService e = 1517 new ThreadPoolExecutor(2, 2, 1518 LONG_DELAY_MS, MILLISECONDS, 1519 new ArrayBlockingQueue<Runnable>(10)); 1520 try (PoolCleaner cleaner = cleaner(e)) { 1521 List<Callable<String>> l = new ArrayList<Callable<String>>(); 1522 l.add(latchAwaitingStringTask(latch)); 1523 l.add(null); 1524 try { 1525 e.invokeAny(l); 1526 shouldThrow(); 1527 } catch (NullPointerException success) {} 1528 latch.countDown(); 1529 } 1530 } 1531 1532 /** 1533 * invokeAny(c) throws ExecutionException if no task completes 1534 */ 1535 public void testInvokeAny4() throws Exception { 1536 final ExecutorService e = 1537 new ThreadPoolExecutor(2, 2, 1538 LONG_DELAY_MS, MILLISECONDS, 1539 new ArrayBlockingQueue<Runnable>(10)); 1540 try (PoolCleaner cleaner = cleaner(e)) { 1541 List<Callable<String>> l = new ArrayList<Callable<String>>(); 1542 l.add(new NPETask()); 1543 try { 1544 e.invokeAny(l); 1545 shouldThrow(); 1546 } catch (ExecutionException success) { 1547 assertTrue(success.getCause() instanceof NullPointerException); 1548 } 1549 } 1550 } 1551 1552 /** 1553 * invokeAny(c) returns result of some task 1554 */ 1555 public void testInvokeAny5() throws Exception { 1556 final ExecutorService e = 1557 new ThreadPoolExecutor(2, 2, 1558 LONG_DELAY_MS, MILLISECONDS, 1559 new ArrayBlockingQueue<Runnable>(10)); 1560 try (PoolCleaner cleaner = cleaner(e)) { 1561 List<Callable<String>> l = new ArrayList<Callable<String>>(); 1562 l.add(new StringTask()); 1563 l.add(new StringTask()); 1564 String result = e.invokeAny(l); 1565 assertSame(TEST_STRING, result); 1566 } 1567 } 1568 1569 /** 1570 * invokeAll(null) throws NPE 1571 */ 1572 public void testInvokeAll1() throws Exception { 1573 final ExecutorService e = 1574 new ThreadPoolExecutor(2, 2, 1575 LONG_DELAY_MS, MILLISECONDS, 1576 new ArrayBlockingQueue<Runnable>(10)); 1577 try (PoolCleaner cleaner = cleaner(e)) { 1578 try { 1579 e.invokeAll(null); 1580 shouldThrow(); 1581 } catch (NullPointerException success) {} 1582 } 1583 } 1584 1585 /** 1586 * invokeAll(empty collection) returns empty collection 1587 */ 1588 public void testInvokeAll2() throws InterruptedException { 1589 final ExecutorService e = 1590 new ThreadPoolExecutor(2, 2, 1591 LONG_DELAY_MS, MILLISECONDS, 1592 new ArrayBlockingQueue<Runnable>(10)); 1593 try (PoolCleaner cleaner = cleaner(e)) { 1594 List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>()); 1595 assertTrue(r.isEmpty()); 1596 } 1597 } 1598 1599 /** 1600 * invokeAll(c) throws NPE if c has null elements 1601 */ 1602 public void testInvokeAll3() throws Exception { 1603 final ExecutorService e = 1604 new ThreadPoolExecutor(2, 2, 1605 LONG_DELAY_MS, MILLISECONDS, 1606 new ArrayBlockingQueue<Runnable>(10)); 1607 try (PoolCleaner cleaner = cleaner(e)) { 1608 List<Callable<String>> l = new ArrayList<Callable<String>>(); 1609 l.add(new StringTask()); 1610 l.add(null); 1611 try { 1612 e.invokeAll(l); 1613 shouldThrow(); 1614 } catch (NullPointerException success) {} 1615 } 1616 } 1617 1618 /** 1619 * get of element of invokeAll(c) throws exception on failed task 1620 */ 1621 public void testInvokeAll4() throws Exception { 1622 final ExecutorService e = 1623 new ThreadPoolExecutor(2, 2, 1624 LONG_DELAY_MS, MILLISECONDS, 1625 new ArrayBlockingQueue<Runnable>(10)); 1626 try (PoolCleaner cleaner = cleaner(e)) { 1627 List<Callable<String>> l = new ArrayList<Callable<String>>(); 1628 l.add(new NPETask()); 1629 List<Future<String>> futures = e.invokeAll(l); 1630 assertEquals(1, futures.size()); 1631 try { 1632 futures.get(0).get(); 1633 shouldThrow(); 1634 } catch (ExecutionException success) { 1635 assertTrue(success.getCause() instanceof NullPointerException); 1636 } 1637 } 1638 } 1639 1640 /** 1641 * invokeAll(c) returns results of all completed tasks 1642 */ 1643 public void testInvokeAll5() throws Exception { 1644 final ExecutorService e = 1645 new ThreadPoolExecutor(2, 2, 1646 LONG_DELAY_MS, MILLISECONDS, 1647 new ArrayBlockingQueue<Runnable>(10)); 1648 try (PoolCleaner cleaner = cleaner(e)) { 1649 List<Callable<String>> l = new ArrayList<Callable<String>>(); 1650 l.add(new StringTask()); 1651 l.add(new StringTask()); 1652 List<Future<String>> futures = e.invokeAll(l); 1653 assertEquals(2, futures.size()); 1654 for (Future<String> future : futures) 1655 assertSame(TEST_STRING, future.get()); 1656 } 1657 } 1658 1659 /** 1660 * timed invokeAny(null) throws NPE 1661 */ 1662 public void testTimedInvokeAny1() throws Exception { 1663 final ExecutorService e = 1664 new ThreadPoolExecutor(2, 2, 1665 LONG_DELAY_MS, MILLISECONDS, 1666 new ArrayBlockingQueue<Runnable>(10)); 1667 try (PoolCleaner cleaner = cleaner(e)) { 1668 try { 1669 e.invokeAny(null, MEDIUM_DELAY_MS, MILLISECONDS); 1670 shouldThrow(); 1671 } catch (NullPointerException success) {} 1672 } 1673 } 1674 1675 /** 1676 * timed invokeAny(,,null) throws NPE 1677 */ 1678 public void testTimedInvokeAnyNullTimeUnit() throws Exception { 1679 final ExecutorService e = 1680 new ThreadPoolExecutor(2, 2, 1681 LONG_DELAY_MS, MILLISECONDS, 1682 new ArrayBlockingQueue<Runnable>(10)); 1683 try (PoolCleaner cleaner = cleaner(e)) { 1684 List<Callable<String>> l = new ArrayList<Callable<String>>(); 1685 l.add(new StringTask()); 1686 try { 1687 e.invokeAny(l, MEDIUM_DELAY_MS, null); 1688 shouldThrow(); 1689 } catch (NullPointerException success) {} 1690 } 1691 } 1692 1693 /** 1694 * timed invokeAny(empty collection) throws IAE 1695 */ 1696 public void testTimedInvokeAny2() throws Exception { 1697 final ExecutorService e = 1698 new ThreadPoolExecutor(2, 2, 1699 LONG_DELAY_MS, MILLISECONDS, 1700 new ArrayBlockingQueue<Runnable>(10)); 1701 try (PoolCleaner cleaner = cleaner(e)) { 1702 try { 1703 e.invokeAny(new ArrayList<Callable<String>>(), 1704 MEDIUM_DELAY_MS, MILLISECONDS); 1705 shouldThrow(); 1706 } catch (IllegalArgumentException success) {} 1707 } 1708 } 1709 1710 /** 1711 * timed invokeAny(c) throws NPE if c has null elements 1712 */ 1713 public void testTimedInvokeAny3() throws Exception { 1714 final CountDownLatch latch = new CountDownLatch(1); 1715 final ExecutorService e = 1716 new ThreadPoolExecutor(2, 2, 1717 LONG_DELAY_MS, MILLISECONDS, 1718 new ArrayBlockingQueue<Runnable>(10)); 1719 try (PoolCleaner cleaner = cleaner(e)) { 1720 List<Callable<String>> l = new ArrayList<Callable<String>>(); 1721 l.add(latchAwaitingStringTask(latch)); 1722 l.add(null); 1723 try { 1724 e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS); 1725 shouldThrow(); 1726 } catch (NullPointerException success) {} 1727 latch.countDown(); 1728 } 1729 } 1730 1731 /** 1732 * timed invokeAny(c) throws ExecutionException if no task completes 1733 */ 1734 public void testTimedInvokeAny4() throws Exception { 1735 final ExecutorService e = 1736 new ThreadPoolExecutor(2, 2, 1737 LONG_DELAY_MS, MILLISECONDS, 1738 new ArrayBlockingQueue<Runnable>(10)); 1739 try (PoolCleaner cleaner = cleaner(e)) { 1740 long startTime = System.nanoTime(); 1741 List<Callable<String>> l = new ArrayList<Callable<String>>(); 1742 l.add(new NPETask()); 1743 try { 1744 e.invokeAny(l, LONG_DELAY_MS, MILLISECONDS); 1745 shouldThrow(); 1746 } catch (ExecutionException success) { 1747 assertTrue(success.getCause() instanceof NullPointerException); 1748 } 1749 assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS); 1750 } 1751 } 1752 1753 /** 1754 * timed invokeAny(c) returns result of some task 1755 */ 1756 public void testTimedInvokeAny5() throws Exception { 1757 final ExecutorService e = 1758 new ThreadPoolExecutor(2, 2, 1759 LONG_DELAY_MS, MILLISECONDS, 1760 new ArrayBlockingQueue<Runnable>(10)); 1761 try (PoolCleaner cleaner = cleaner(e)) { 1762 long startTime = System.nanoTime(); 1763 List<Callable<String>> l = new ArrayList<Callable<String>>(); 1764 l.add(new StringTask()); 1765 l.add(new StringTask()); 1766 String result = e.invokeAny(l, LONG_DELAY_MS, MILLISECONDS); 1767 assertSame(TEST_STRING, result); 1768 assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS); 1769 } 1770 } 1771 1772 /** 1773 * timed invokeAll(null) throws NPE 1774 */ 1775 public void testTimedInvokeAll1() throws Exception { 1776 final ExecutorService e = 1777 new ThreadPoolExecutor(2, 2, 1778 LONG_DELAY_MS, MILLISECONDS, 1779 new ArrayBlockingQueue<Runnable>(10)); 1780 try (PoolCleaner cleaner = cleaner(e)) { 1781 try { 1782 e.invokeAll(null, MEDIUM_DELAY_MS, MILLISECONDS); 1783 shouldThrow(); 1784 } catch (NullPointerException success) {} 1785 } 1786 } 1787 1788 /** 1789 * timed invokeAll(,,null) throws NPE 1790 */ 1791 public void testTimedInvokeAllNullTimeUnit() throws Exception { 1792 final ExecutorService e = 1793 new ThreadPoolExecutor(2, 2, 1794 LONG_DELAY_MS, MILLISECONDS, 1795 new ArrayBlockingQueue<Runnable>(10)); 1796 try (PoolCleaner cleaner = cleaner(e)) { 1797 List<Callable<String>> l = new ArrayList<Callable<String>>(); 1798 l.add(new StringTask()); 1799 try { 1800 e.invokeAll(l, MEDIUM_DELAY_MS, null); 1801 shouldThrow(); 1802 } catch (NullPointerException success) {} 1803 } 1804 } 1805 1806 /** 1807 * timed invokeAll(empty collection) returns empty collection 1808 */ 1809 public void testTimedInvokeAll2() throws InterruptedException { 1810 final ExecutorService e = 1811 new ThreadPoolExecutor(2, 2, 1812 LONG_DELAY_MS, MILLISECONDS, 1813 new ArrayBlockingQueue<Runnable>(10)); 1814 try (PoolCleaner cleaner = cleaner(e)) { 1815 List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>(), 1816 MEDIUM_DELAY_MS, MILLISECONDS); 1817 assertTrue(r.isEmpty()); 1818 } 1819 } 1820 1821 /** 1822 * timed invokeAll(c) throws NPE if c has null elements 1823 */ 1824 public void testTimedInvokeAll3() throws Exception { 1825 final ExecutorService e = 1826 new ThreadPoolExecutor(2, 2, 1827 LONG_DELAY_MS, MILLISECONDS, 1828 new ArrayBlockingQueue<Runnable>(10)); 1829 try (PoolCleaner cleaner = cleaner(e)) { 1830 List<Callable<String>> l = new ArrayList<Callable<String>>(); 1831 l.add(new StringTask()); 1832 l.add(null); 1833 try { 1834 e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS); 1835 shouldThrow(); 1836 } catch (NullPointerException success) {} 1837 } 1838 } 1839 1840 /** 1841 * get of element of invokeAll(c) throws exception on failed task 1842 */ 1843 public void testTimedInvokeAll4() throws Exception { 1844 final ExecutorService e = 1845 new ThreadPoolExecutor(2, 2, 1846 LONG_DELAY_MS, MILLISECONDS, 1847 new ArrayBlockingQueue<Runnable>(10)); 1848 try (PoolCleaner cleaner = cleaner(e)) { 1849 List<Callable<String>> l = new ArrayList<Callable<String>>(); 1850 l.add(new NPETask()); 1851 List<Future<String>> futures = 1852 e.invokeAll(l, LONG_DELAY_MS, MILLISECONDS); 1853 assertEquals(1, futures.size()); 1854 try { 1855 futures.get(0).get(); 1856 shouldThrow(); 1857 } catch (ExecutionException success) { 1858 assertTrue(success.getCause() instanceof NullPointerException); 1859 } 1860 } 1861 } 1862 1863 /** 1864 * timed invokeAll(c) returns results of all completed tasks 1865 */ 1866 public void testTimedInvokeAll5() throws Exception { 1867 final ExecutorService e = 1868 new ThreadPoolExecutor(2, 2, 1869 LONG_DELAY_MS, MILLISECONDS, 1870 new ArrayBlockingQueue<Runnable>(10)); 1871 try (PoolCleaner cleaner = cleaner(e)) { 1872 List<Callable<String>> l = new ArrayList<Callable<String>>(); 1873 l.add(new StringTask()); 1874 l.add(new StringTask()); 1875 List<Future<String>> futures = 1876 e.invokeAll(l, LONG_DELAY_MS, MILLISECONDS); 1877 assertEquals(2, futures.size()); 1878 for (Future<String> future : futures) 1879 assertSame(TEST_STRING, future.get()); 1880 } 1881 } 1882 1883 /** 1884 * timed invokeAll(c) cancels tasks not completed by timeout 1885 */ 1886 public void testTimedInvokeAll6() throws Exception { 1887 for (long timeout = timeoutMillis();;) { 1888 final CountDownLatch done = new CountDownLatch(1); 1889 final Callable<String> waiter = new CheckedCallable<String>() { 1890 public String realCall() { 1891 try { done.await(LONG_DELAY_MS, MILLISECONDS); } 1892 catch (InterruptedException ok) {} 1893 return "1"; }}; 1894 final ExecutorService p = 1895 new ThreadPoolExecutor(2, 2, 1896 LONG_DELAY_MS, MILLISECONDS, 1897 new ArrayBlockingQueue<Runnable>(10)); 1898 try (PoolCleaner cleaner = cleaner(p, done)) { 1899 List<Callable<String>> tasks = new ArrayList<>(); 1900 tasks.add(new StringTask("0")); 1901 tasks.add(waiter); 1902 tasks.add(new StringTask("2")); 1903 long startTime = System.nanoTime(); 1904 List<Future<String>> futures = 1905 p.invokeAll(tasks, timeout, MILLISECONDS); 1906 assertEquals(tasks.size(), futures.size()); 1907 assertTrue(millisElapsedSince(startTime) >= timeout); 1908 for (Future future : futures) 1909 assertTrue(future.isDone()); 1910 assertTrue(futures.get(1).isCancelled()); 1911 try { 1912 assertEquals("0", futures.get(0).get()); 1913 assertEquals("2", futures.get(2).get()); 1914 break; 1915 } catch (CancellationException retryWithLongerTimeout) { 1916 timeout *= 2; 1917 if (timeout >= LONG_DELAY_MS / 2) 1918 fail("expected exactly one task to be cancelled"); 1919 } 1920 } 1921 } 1922 } 1923 1924 /** 1925 * Execution continues if there is at least one thread even if 1926 * thread factory fails to create more 1927 */ 1928 public void testFailingThreadFactory() throws InterruptedException { 1929 final ExecutorService e = 1930 new ThreadPoolExecutor(100, 100, 1931 LONG_DELAY_MS, MILLISECONDS, 1932 new LinkedBlockingQueue<Runnable>(), 1933 new FailingThreadFactory()); 1934 try (PoolCleaner cleaner = cleaner(e)) { 1935 final int TASKS = 100; 1936 final CountDownLatch done = new CountDownLatch(TASKS); 1937 for (int k = 0; k < TASKS; ++k) 1938 e.execute(new CheckedRunnable() { 1939 public void realRun() { 1940 done.countDown(); 1941 }}); 1942 assertTrue(done.await(LONG_DELAY_MS, MILLISECONDS)); 1943 } 1944 } 1945 1946 /** 1947 * allowsCoreThreadTimeOut is by default false. 1948 */ 1949 public void testAllowsCoreThreadTimeOut() { 1950 final ThreadPoolExecutor p = 1951 new ThreadPoolExecutor(2, 2, 1952 1000, MILLISECONDS, 1953 new ArrayBlockingQueue<Runnable>(10)); 1954 try (PoolCleaner cleaner = cleaner(p)) { 1955 assertFalse(p.allowsCoreThreadTimeOut()); 1956 } 1957 } 1958 1959 /** 1960 * allowCoreThreadTimeOut(true) causes idle threads to time out 1961 */ 1962 public void testAllowCoreThreadTimeOut_true() throws Exception { 1963 long keepAliveTime = timeoutMillis(); 1964 final ThreadPoolExecutor p = 1965 new ThreadPoolExecutor(2, 10, 1966 keepAliveTime, MILLISECONDS, 1967 new ArrayBlockingQueue<Runnable>(10)); 1968 try (PoolCleaner cleaner = cleaner(p)) { 1969 final CountDownLatch threadStarted = new CountDownLatch(1); 1970 p.allowCoreThreadTimeOut(true); 1971 p.execute(new CheckedRunnable() { 1972 public void realRun() { 1973 threadStarted.countDown(); 1974 assertEquals(1, p.getPoolSize()); 1975 }}); 1976 await(threadStarted); 1977 delay(keepAliveTime); 1978 long startTime = System.nanoTime(); 1979 while (p.getPoolSize() > 0 1980 && millisElapsedSince(startTime) < LONG_DELAY_MS) 1981 Thread.yield(); 1982 assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS); 1983 assertEquals(0, p.getPoolSize()); 1984 } 1985 } 1986 1987 /** 1988 * allowCoreThreadTimeOut(false) causes idle threads not to time out 1989 */ 1990 public void testAllowCoreThreadTimeOut_false() throws Exception { 1991 long keepAliveTime = timeoutMillis(); 1992 final ThreadPoolExecutor p = 1993 new ThreadPoolExecutor(2, 10, 1994 keepAliveTime, MILLISECONDS, 1995 new ArrayBlockingQueue<Runnable>(10)); 1996 try (PoolCleaner cleaner = cleaner(p)) { 1997 final CountDownLatch threadStarted = new CountDownLatch(1); 1998 p.allowCoreThreadTimeOut(false); 1999 p.execute(new CheckedRunnable() { 2000 public void realRun() throws InterruptedException { 2001 threadStarted.countDown(); 2002 assertTrue(p.getPoolSize() >= 1); 2003 }}); 2004 delay(2 * keepAliveTime); 2005 assertTrue(p.getPoolSize() >= 1); 2006 } 2007 } 2008 2009 /** 2010 * execute allows the same task to be submitted multiple times, even 2011 * if rejected 2012 */ 2013 public void testRejectedRecycledTask() throws InterruptedException { 2014 final int nTasks = 1000; 2015 final CountDownLatch done = new CountDownLatch(nTasks); 2016 final Runnable recycledTask = new Runnable() { 2017 public void run() { 2018 done.countDown(); 2019 }}; 2020 final ThreadPoolExecutor p = 2021 new ThreadPoolExecutor(1, 30, 2022 60, SECONDS, 2023 new ArrayBlockingQueue(30)); 2024 try (PoolCleaner cleaner = cleaner(p)) { 2025 for (int i = 0; i < nTasks; ++i) { 2026 for (;;) { 2027 try { 2028 p.execute(recycledTask); 2029 break; 2030 } 2031 catch (RejectedExecutionException ignore) {} 2032 } 2033 } 2034 // enough time to run all tasks 2035 assertTrue(done.await(nTasks * SHORT_DELAY_MS, MILLISECONDS)); 2036 } 2037 } 2038 2039 /** 2040 * get(cancelled task) throws CancellationException 2041 */ 2042 public void testGet_cancelled() throws Exception { 2043 final CountDownLatch done = new CountDownLatch(1); 2044 final ExecutorService e = 2045 new ThreadPoolExecutor(1, 1, 2046 LONG_DELAY_MS, MILLISECONDS, 2047 new LinkedBlockingQueue<Runnable>()); 2048 try (PoolCleaner cleaner = cleaner(e, done)) { 2049 final CountDownLatch blockerStarted = new CountDownLatch(1); 2050 final List<Future<?>> futures = new ArrayList<>(); 2051 for (int i = 0; i < 2; i++) { 2052 Runnable r = new CheckedRunnable() { public void realRun() 2053 throws Throwable { 2054 blockerStarted.countDown(); 2055 assertTrue(done.await(2 * LONG_DELAY_MS, MILLISECONDS)); 2056 }}; 2057 futures.add(e.submit(r)); 2058 } 2059 await(blockerStarted); 2060 for (Future<?> future : futures) future.cancel(false); 2061 for (Future<?> future : futures) { 2062 try { 2063 future.get(); 2064 shouldThrow(); 2065 } catch (CancellationException success) {} 2066 try { 2067 future.get(LONG_DELAY_MS, MILLISECONDS); 2068 shouldThrow(); 2069 } catch (CancellationException success) {} 2070 assertTrue(future.isCancelled()); 2071 assertTrue(future.isDone()); 2072 } 2073 } 2074 } 2075 2076 } 2077