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