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