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