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