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 { main(String[] args)71 public static void main(String[] args) { 72 main(suite(), args); 73 } suite()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 ExtendedTPE()83 public ExtendedTPE() { 84 super(1, 1, LONG_DELAY_MS, MILLISECONDS, new SynchronousQueue<Runnable>()); 85 } beforeExecute(Thread t, Runnable r)86 protected void beforeExecute(Thread t, Runnable r) { 87 beforeCalled.countDown(); 88 } afterExecute(Runnable r, Throwable t)89 protected void afterExecute(Runnable r, Throwable t) { 90 afterCalled.countDown(); 91 } terminated()92 protected void terminated() { 93 terminatedCalled.countDown(); 94 } 95 beforeCalled()96 public boolean beforeCalled() { 97 return beforeCalled.getCount() == 0; 98 } afterCalled()99 public boolean afterCalled() { 100 return afterCalled.getCount() == 0; 101 } terminatedCalled()102 public boolean terminatedCalled() { 103 return terminatedCalled.getCount() == 0; 104 } 105 } 106 107 static class FailingThreadFactory implements ThreadFactory { 108 int calls = 0; newThread(Runnable r)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 */ testExecute()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 */ testGetActiveCount()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 */ testPrestartCoreThread()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 */ testPrestartAllCoreThreads()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 */ testGetCompletedTaskCount()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 */ testGetCorePoolSize()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 */ testGetKeepAliveTime()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 */ testGetThreadFactory()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 */ testSetThreadFactory()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 */ testSetThreadFactoryNull()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 */ testDefaultRejectedExecutionHandler()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 */ testGetRejectedExecutionHandler()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 */ testSetRejectedExecutionHandler()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 */ testSetRejectedExecutionHandlerNull()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 */ testGetLargestPoolSize()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 */ testGetMaximumPoolSize()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 */ testGetPoolSize()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 */ testGetTaskCount()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 */ testIsShutdown()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 */ testAwaitTermination_timesOut()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 */ testIsTerminated()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 */ testIsTerminating()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 */ testGetQueue()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[] rtasks = new FutureTask[5]; 594 @SuppressWarnings("unchecked") 595 FutureTask<Boolean>[] tasks = (FutureTask<Boolean>[])rtasks; 596 for (int i = 0; i < tasks.length; i++) { 597 Callable<Boolean> task = new CheckedCallable<>() { 598 public Boolean realCall() throws InterruptedException { 599 threadStarted.countDown(); 600 assertSame(q, p.getQueue()); 601 await(done); 602 return Boolean.TRUE; 603 }}; 604 tasks[i] = new FutureTask<>(task); 605 p.execute(tasks[i]); 606 } 607 await(threadStarted); 608 assertSame(q, p.getQueue()); 609 assertFalse(q.contains(tasks[0])); 610 assertTrue(q.contains(tasks[tasks.length - 1])); 611 assertEquals(tasks.length - 1, q.size()); 612 } 613 } 614 615 /** 616 * remove(task) removes queued task, and fails to remove active task 617 */ testRemove()618 public void testRemove() throws InterruptedException { 619 final CountDownLatch done = new CountDownLatch(1); 620 BlockingQueue<Runnable> q = new ArrayBlockingQueue<>(10); 621 final ThreadPoolExecutor p = 622 new ThreadPoolExecutor(1, 1, 623 LONG_DELAY_MS, MILLISECONDS, 624 q); 625 try (PoolCleaner cleaner = cleaner(p, done)) { 626 Runnable[] tasks = new Runnable[6]; 627 final CountDownLatch threadStarted = new CountDownLatch(1); 628 for (int i = 0; i < tasks.length; i++) { 629 tasks[i] = new CheckedRunnable() { 630 public void realRun() throws InterruptedException { 631 threadStarted.countDown(); 632 await(done); 633 }}; 634 p.execute(tasks[i]); 635 } 636 await(threadStarted); 637 assertFalse(p.remove(tasks[0])); 638 assertTrue(q.contains(tasks[4])); 639 assertTrue(q.contains(tasks[3])); 640 assertTrue(p.remove(tasks[4])); 641 assertFalse(p.remove(tasks[4])); 642 assertFalse(q.contains(tasks[4])); 643 assertTrue(q.contains(tasks[3])); 644 assertTrue(p.remove(tasks[3])); 645 assertFalse(q.contains(tasks[3])); 646 } 647 } 648 649 /** 650 * purge removes cancelled tasks from the queue 651 */ testPurge()652 public void testPurge() throws InterruptedException { 653 final CountDownLatch threadStarted = new CountDownLatch(1); 654 final CountDownLatch done = new CountDownLatch(1); 655 final BlockingQueue<Runnable> q = new ArrayBlockingQueue<>(10); 656 final ThreadPoolExecutor p = 657 new ThreadPoolExecutor(1, 1, 658 LONG_DELAY_MS, MILLISECONDS, 659 q); 660 try (PoolCleaner cleaner = cleaner(p, done)) { 661 FutureTask[] rtasks = new FutureTask[5]; 662 @SuppressWarnings("unchecked") 663 FutureTask<Boolean>[] tasks = (FutureTask<Boolean>[])rtasks; 664 for (int i = 0; i < tasks.length; i++) { 665 Callable<Boolean> task = new CheckedCallable<>() { 666 public Boolean realCall() throws InterruptedException { 667 threadStarted.countDown(); 668 await(done); 669 return Boolean.TRUE; 670 }}; 671 tasks[i] = new FutureTask<>(task); 672 p.execute(tasks[i]); 673 } 674 await(threadStarted); 675 assertEquals(tasks.length, p.getTaskCount()); 676 assertEquals(tasks.length - 1, q.size()); 677 assertEquals(1L, p.getActiveCount()); 678 assertEquals(0L, p.getCompletedTaskCount()); 679 tasks[4].cancel(true); 680 tasks[3].cancel(false); 681 p.purge(); 682 assertEquals(tasks.length - 3, q.size()); 683 assertEquals(tasks.length - 2, p.getTaskCount()); 684 p.purge(); // Nothing to do 685 assertEquals(tasks.length - 3, q.size()); 686 assertEquals(tasks.length - 2, p.getTaskCount()); 687 } 688 } 689 690 /** 691 * shutdownNow returns a list containing tasks that were not run, 692 * and those tasks are drained from the queue 693 */ testShutdownNow()694 public void testShutdownNow() throws InterruptedException { 695 final int poolSize = 2; 696 final int count = 5; 697 final AtomicInteger ran = new AtomicInteger(0); 698 final ThreadPoolExecutor p = 699 new ThreadPoolExecutor(poolSize, poolSize, 700 LONG_DELAY_MS, MILLISECONDS, 701 new ArrayBlockingQueue<Runnable>(10)); 702 final CountDownLatch threadsStarted = new CountDownLatch(poolSize); 703 Runnable waiter = new CheckedRunnable() { public void realRun() { 704 threadsStarted.countDown(); 705 try { 706 MILLISECONDS.sleep(LONGER_DELAY_MS); 707 } catch (InterruptedException success) {} 708 ran.getAndIncrement(); 709 }}; 710 for (int i = 0; i < count; i++) 711 p.execute(waiter); 712 await(threadsStarted); 713 assertEquals(poolSize, p.getActiveCount()); 714 assertEquals(0, p.getCompletedTaskCount()); 715 final List<Runnable> queuedTasks; 716 try { 717 queuedTasks = p.shutdownNow(); 718 } catch (SecurityException ok) { 719 return; // Allowed in case test doesn't have privs 720 } 721 assertTrue(p.isShutdown()); 722 assertTrue(p.getQueue().isEmpty()); 723 assertEquals(count - poolSize, queuedTasks.size()); 724 assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS)); 725 assertTrue(p.isTerminated()); 726 assertEquals(poolSize, ran.get()); 727 assertEquals(poolSize, p.getCompletedTaskCount()); 728 } 729 730 // Exception Tests 731 732 /** 733 * Constructor throws if corePoolSize argument is less than zero 734 */ testConstructor1()735 public void testConstructor1() { 736 try { 737 new ThreadPoolExecutor(-1, 1, 1L, SECONDS, 738 new ArrayBlockingQueue<Runnable>(10)); 739 shouldThrow(); 740 } catch (IllegalArgumentException success) {} 741 } 742 743 /** 744 * Constructor throws if maximumPoolSize is less than zero 745 */ testConstructor2()746 public void testConstructor2() { 747 try { 748 new ThreadPoolExecutor(1, -1, 1L, SECONDS, 749 new ArrayBlockingQueue<Runnable>(10)); 750 shouldThrow(); 751 } catch (IllegalArgumentException success) {} 752 } 753 754 /** 755 * Constructor throws if maximumPoolSize is equal to zero 756 */ testConstructor3()757 public void testConstructor3() { 758 try { 759 new ThreadPoolExecutor(1, 0, 1L, SECONDS, 760 new ArrayBlockingQueue<Runnable>(10)); 761 shouldThrow(); 762 } catch (IllegalArgumentException success) {} 763 } 764 765 /** 766 * Constructor throws if keepAliveTime is less than zero 767 */ testConstructor4()768 public void testConstructor4() { 769 try { 770 new ThreadPoolExecutor(1, 2, -1L, SECONDS, 771 new ArrayBlockingQueue<Runnable>(10)); 772 shouldThrow(); 773 } catch (IllegalArgumentException success) {} 774 } 775 776 /** 777 * Constructor throws if corePoolSize is greater than the maximumPoolSize 778 */ testConstructor5()779 public void testConstructor5() { 780 try { 781 new ThreadPoolExecutor(2, 1, 1L, SECONDS, 782 new ArrayBlockingQueue<Runnable>(10)); 783 shouldThrow(); 784 } catch (IllegalArgumentException success) {} 785 } 786 787 /** 788 * Constructor throws if workQueue is set to null 789 */ testConstructorNullPointerException()790 public void testConstructorNullPointerException() { 791 try { 792 new ThreadPoolExecutor(1, 2, 1L, SECONDS, 793 (BlockingQueue<Runnable>) null); 794 shouldThrow(); 795 } catch (NullPointerException success) {} 796 } 797 798 /** 799 * Constructor throws if corePoolSize argument is less than zero 800 */ testConstructor6()801 public void testConstructor6() { 802 try { 803 new ThreadPoolExecutor(-1, 1, 1L, SECONDS, 804 new ArrayBlockingQueue<Runnable>(10), 805 new SimpleThreadFactory()); 806 shouldThrow(); 807 } catch (IllegalArgumentException success) {} 808 } 809 810 /** 811 * Constructor throws if maximumPoolSize is less than zero 812 */ testConstructor7()813 public void testConstructor7() { 814 try { 815 new ThreadPoolExecutor(1, -1, 1L, SECONDS, 816 new ArrayBlockingQueue<Runnable>(10), 817 new SimpleThreadFactory()); 818 shouldThrow(); 819 } catch (IllegalArgumentException success) {} 820 } 821 822 /** 823 * Constructor throws if maximumPoolSize is equal to zero 824 */ testConstructor8()825 public void testConstructor8() { 826 try { 827 new ThreadPoolExecutor(1, 0, 1L, SECONDS, 828 new ArrayBlockingQueue<Runnable>(10), 829 new SimpleThreadFactory()); 830 shouldThrow(); 831 } catch (IllegalArgumentException success) {} 832 } 833 834 /** 835 * Constructor throws if keepAliveTime is less than zero 836 */ testConstructor9()837 public void testConstructor9() { 838 try { 839 new ThreadPoolExecutor(1, 2, -1L, SECONDS, 840 new ArrayBlockingQueue<Runnable>(10), 841 new SimpleThreadFactory()); 842 shouldThrow(); 843 } catch (IllegalArgumentException success) {} 844 } 845 846 /** 847 * Constructor throws if corePoolSize is greater than the maximumPoolSize 848 */ testConstructor10()849 public void testConstructor10() { 850 try { 851 new ThreadPoolExecutor(2, 1, 1L, SECONDS, 852 new ArrayBlockingQueue<Runnable>(10), 853 new SimpleThreadFactory()); 854 shouldThrow(); 855 } catch (IllegalArgumentException success) {} 856 } 857 858 /** 859 * Constructor throws if workQueue is set to null 860 */ testConstructorNullPointerException2()861 public void testConstructorNullPointerException2() { 862 try { 863 new ThreadPoolExecutor(1, 2, 1L, SECONDS, 864 (BlockingQueue<Runnable>) null, 865 new SimpleThreadFactory()); 866 shouldThrow(); 867 } catch (NullPointerException success) {} 868 } 869 870 /** 871 * Constructor throws if threadFactory is set to null 872 */ testConstructorNullPointerException3()873 public void testConstructorNullPointerException3() { 874 try { 875 new ThreadPoolExecutor(1, 2, 1L, SECONDS, 876 new ArrayBlockingQueue<Runnable>(10), 877 (ThreadFactory) null); 878 shouldThrow(); 879 } catch (NullPointerException success) {} 880 } 881 882 /** 883 * Constructor throws if corePoolSize argument is less than zero 884 */ testConstructor11()885 public void testConstructor11() { 886 try { 887 new ThreadPoolExecutor(-1, 1, 1L, SECONDS, 888 new ArrayBlockingQueue<Runnable>(10), 889 new NoOpREHandler()); 890 shouldThrow(); 891 } catch (IllegalArgumentException success) {} 892 } 893 894 /** 895 * Constructor throws if maximumPoolSize is less than zero 896 */ testConstructor12()897 public void testConstructor12() { 898 try { 899 new ThreadPoolExecutor(1, -1, 1L, SECONDS, 900 new ArrayBlockingQueue<Runnable>(10), 901 new NoOpREHandler()); 902 shouldThrow(); 903 } catch (IllegalArgumentException success) {} 904 } 905 906 /** 907 * Constructor throws if maximumPoolSize is equal to zero 908 */ testConstructor13()909 public void testConstructor13() { 910 try { 911 new ThreadPoolExecutor(1, 0, 1L, SECONDS, 912 new ArrayBlockingQueue<Runnable>(10), 913 new NoOpREHandler()); 914 shouldThrow(); 915 } catch (IllegalArgumentException success) {} 916 } 917 918 /** 919 * Constructor throws if keepAliveTime is less than zero 920 */ testConstructor14()921 public void testConstructor14() { 922 try { 923 new ThreadPoolExecutor(1, 2, -1L, SECONDS, 924 new ArrayBlockingQueue<Runnable>(10), 925 new NoOpREHandler()); 926 shouldThrow(); 927 } catch (IllegalArgumentException success) {} 928 } 929 930 /** 931 * Constructor throws if corePoolSize is greater than the maximumPoolSize 932 */ testConstructor15()933 public void testConstructor15() { 934 try { 935 new ThreadPoolExecutor(2, 1, 1L, SECONDS, 936 new ArrayBlockingQueue<Runnable>(10), 937 new NoOpREHandler()); 938 shouldThrow(); 939 } catch (IllegalArgumentException success) {} 940 } 941 942 /** 943 * Constructor throws if workQueue is set to null 944 */ testConstructorNullPointerException4()945 public void testConstructorNullPointerException4() { 946 try { 947 new ThreadPoolExecutor(1, 2, 1L, SECONDS, 948 (BlockingQueue<Runnable>) null, 949 new NoOpREHandler()); 950 shouldThrow(); 951 } catch (NullPointerException success) {} 952 } 953 954 /** 955 * Constructor throws if handler is set to null 956 */ testConstructorNullPointerException5()957 public void testConstructorNullPointerException5() { 958 try { 959 new ThreadPoolExecutor(1, 2, 1L, SECONDS, 960 new ArrayBlockingQueue<Runnable>(10), 961 (RejectedExecutionHandler) null); 962 shouldThrow(); 963 } catch (NullPointerException success) {} 964 } 965 966 /** 967 * Constructor throws if corePoolSize argument is less than zero 968 */ testConstructor16()969 public void testConstructor16() { 970 try { 971 new ThreadPoolExecutor(-1, 1, 1L, SECONDS, 972 new ArrayBlockingQueue<Runnable>(10), 973 new SimpleThreadFactory(), 974 new NoOpREHandler()); 975 shouldThrow(); 976 } catch (IllegalArgumentException success) {} 977 } 978 979 /** 980 * Constructor throws if maximumPoolSize is less than zero 981 */ testConstructor17()982 public void testConstructor17() { 983 try { 984 new ThreadPoolExecutor(1, -1, 1L, SECONDS, 985 new ArrayBlockingQueue<Runnable>(10), 986 new SimpleThreadFactory(), 987 new NoOpREHandler()); 988 shouldThrow(); 989 } catch (IllegalArgumentException success) {} 990 } 991 992 /** 993 * Constructor throws if maximumPoolSize is equal to zero 994 */ testConstructor18()995 public void testConstructor18() { 996 try { 997 new ThreadPoolExecutor(1, 0, 1L, SECONDS, 998 new ArrayBlockingQueue<Runnable>(10), 999 new SimpleThreadFactory(), 1000 new NoOpREHandler()); 1001 shouldThrow(); 1002 } catch (IllegalArgumentException success) {} 1003 } 1004 1005 /** 1006 * Constructor throws if keepAliveTime is less than zero 1007 */ testConstructor19()1008 public void testConstructor19() { 1009 try { 1010 new ThreadPoolExecutor(1, 2, -1L, SECONDS, 1011 new ArrayBlockingQueue<Runnable>(10), 1012 new SimpleThreadFactory(), 1013 new NoOpREHandler()); 1014 shouldThrow(); 1015 } catch (IllegalArgumentException success) {} 1016 } 1017 1018 /** 1019 * Constructor throws if corePoolSize is greater than the maximumPoolSize 1020 */ testConstructor20()1021 public void testConstructor20() { 1022 try { 1023 new ThreadPoolExecutor(2, 1, 1L, SECONDS, 1024 new ArrayBlockingQueue<Runnable>(10), 1025 new SimpleThreadFactory(), 1026 new NoOpREHandler()); 1027 shouldThrow(); 1028 } catch (IllegalArgumentException success) {} 1029 } 1030 1031 /** 1032 * Constructor throws if workQueue is null 1033 */ testConstructorNullPointerException6()1034 public void testConstructorNullPointerException6() { 1035 try { 1036 new ThreadPoolExecutor(1, 2, 1L, SECONDS, 1037 (BlockingQueue<Runnable>) null, 1038 new SimpleThreadFactory(), 1039 new NoOpREHandler()); 1040 shouldThrow(); 1041 } catch (NullPointerException success) {} 1042 } 1043 1044 /** 1045 * Constructor throws if handler is null 1046 */ testConstructorNullPointerException7()1047 public void testConstructorNullPointerException7() { 1048 try { 1049 new ThreadPoolExecutor(1, 2, 1L, SECONDS, 1050 new ArrayBlockingQueue<Runnable>(10), 1051 new SimpleThreadFactory(), 1052 (RejectedExecutionHandler) null); 1053 shouldThrow(); 1054 } catch (NullPointerException success) {} 1055 } 1056 1057 /** 1058 * Constructor throws if ThreadFactory is null 1059 */ testConstructorNullPointerException8()1060 public void testConstructorNullPointerException8() { 1061 try { 1062 new ThreadPoolExecutor(1, 2, 1L, SECONDS, 1063 new ArrayBlockingQueue<Runnable>(10), 1064 (ThreadFactory) null, 1065 new NoOpREHandler()); 1066 shouldThrow(); 1067 } catch (NullPointerException success) {} 1068 } 1069 1070 /** 1071 * get of submitted callable throws InterruptedException if interrupted 1072 */ testInterruptedSubmit()1073 public void testInterruptedSubmit() throws InterruptedException { 1074 final CountDownLatch done = new CountDownLatch(1); 1075 final ThreadPoolExecutor p = 1076 new ThreadPoolExecutor(1, 1, 1077 60, SECONDS, 1078 new ArrayBlockingQueue<Runnable>(10)); 1079 1080 try (PoolCleaner cleaner = cleaner(p, done)) { 1081 final CountDownLatch threadStarted = new CountDownLatch(1); 1082 Thread t = newStartedThread(new CheckedInterruptedRunnable() { 1083 public void realRun() throws Exception { 1084 Callable<Boolean> task = new CheckedCallable<>() { 1085 public Boolean realCall() throws InterruptedException { 1086 threadStarted.countDown(); 1087 await(done); 1088 return Boolean.TRUE; 1089 }}; 1090 p.submit(task).get(); 1091 }}); 1092 1093 await(threadStarted); // ensure quiescence 1094 t.interrupt(); 1095 awaitTermination(t); 1096 } 1097 } 1098 1099 /** 1100 * Submitted tasks are rejected when saturated or shutdown 1101 */ testSubmittedTasksRejectedWhenSaturatedOrShutdown()1102 public void testSubmittedTasksRejectedWhenSaturatedOrShutdown() throws InterruptedException { 1103 final ThreadPoolExecutor p = new ThreadPoolExecutor( 1104 1, 1, 1, SECONDS, new ArrayBlockingQueue<Runnable>(1)); 1105 final int saturatedSize = saturatedSize(p); 1106 final ThreadLocalRandom rnd = ThreadLocalRandom.current(); 1107 final CountDownLatch threadsStarted = new CountDownLatch(p.getMaximumPoolSize()); 1108 final CountDownLatch done = new CountDownLatch(1); 1109 final Runnable r = () -> { 1110 threadsStarted.countDown(); 1111 for (;;) { 1112 try { 1113 done.await(); 1114 return; 1115 } catch (InterruptedException shutdownNowDeliberatelyIgnored) {} 1116 }}; 1117 final Callable<Boolean> c = () -> { 1118 threadsStarted.countDown(); 1119 for (;;) { 1120 try { 1121 done.await(); 1122 return Boolean.TRUE; 1123 } catch (InterruptedException shutdownNowDeliberatelyIgnored) {} 1124 }}; 1125 final boolean shutdownNow = rnd.nextBoolean(); 1126 1127 try (PoolCleaner cleaner = cleaner(p, done)) { 1128 // saturate 1129 for (int i = saturatedSize; i--> 0; ) { 1130 switch (rnd.nextInt(4)) { 1131 case 0: p.execute(r); break; 1132 case 1: assertFalse(p.submit(r).isDone()); break; 1133 case 2: assertFalse(p.submit(r, Boolean.TRUE).isDone()); break; 1134 case 3: assertFalse(p.submit(c).isDone()); break; 1135 } 1136 } 1137 1138 await(threadsStarted); 1139 assertTaskSubmissionsAreRejected(p); 1140 1141 if (shutdownNow) 1142 p.shutdownNow(); 1143 else 1144 p.shutdown(); 1145 // Pool is shutdown, but not yet terminated 1146 assertTaskSubmissionsAreRejected(p); 1147 assertFalse(p.isTerminated()); 1148 1149 done.countDown(); // release blocking tasks 1150 assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS)); 1151 1152 assertTaskSubmissionsAreRejected(p); 1153 } 1154 assertEquals(saturatedSize(p) 1155 - (shutdownNow ? p.getQueue().remainingCapacity() : 0), 1156 p.getCompletedTaskCount()); 1157 } 1158 1159 /** 1160 * executor using DiscardOldestPolicy drops oldest task if saturated. 1161 */ testSaturatedExecute_DiscardOldestPolicy()1162 public void testSaturatedExecute_DiscardOldestPolicy() { 1163 final CountDownLatch done = new CountDownLatch(1); 1164 LatchAwaiter r1 = awaiter(done); 1165 LatchAwaiter r2 = awaiter(done); 1166 LatchAwaiter r3 = awaiter(done); 1167 final ThreadPoolExecutor p = 1168 new ThreadPoolExecutor(1, 1, 1169 LONG_DELAY_MS, MILLISECONDS, 1170 new ArrayBlockingQueue<Runnable>(1), 1171 new DiscardOldestPolicy()); 1172 try (PoolCleaner cleaner = cleaner(p, done)) { 1173 assertEquals(LatchAwaiter.NEW, r1.state); 1174 assertEquals(LatchAwaiter.NEW, r2.state); 1175 assertEquals(LatchAwaiter.NEW, r3.state); 1176 p.execute(r1); 1177 p.execute(r2); 1178 assertTrue(p.getQueue().contains(r2)); 1179 p.execute(r3); 1180 assertFalse(p.getQueue().contains(r2)); 1181 assertTrue(p.getQueue().contains(r3)); 1182 } 1183 assertEquals(LatchAwaiter.DONE, r1.state); 1184 assertEquals(LatchAwaiter.NEW, r2.state); 1185 assertEquals(LatchAwaiter.DONE, r3.state); 1186 } 1187 1188 /** 1189 * execute using DiscardOldestPolicy drops task on shutdown 1190 */ testDiscardOldestOnShutdown()1191 public void testDiscardOldestOnShutdown() { 1192 final ThreadPoolExecutor p = 1193 new ThreadPoolExecutor(1, 1, 1194 LONG_DELAY_MS, MILLISECONDS, 1195 new ArrayBlockingQueue<Runnable>(1), 1196 new DiscardOldestPolicy()); 1197 1198 try { p.shutdown(); } catch (SecurityException ok) { return; } 1199 try (PoolCleaner cleaner = cleaner(p)) { 1200 TrackedNoOpRunnable r = new TrackedNoOpRunnable(); 1201 p.execute(r); 1202 assertFalse(r.done); 1203 } 1204 } 1205 1206 /** 1207 * Submitting null tasks throws NullPointerException 1208 */ testNullTaskSubmission()1209 public void testNullTaskSubmission() { 1210 final ThreadPoolExecutor p = 1211 new ThreadPoolExecutor(1, 2, 1212 1L, SECONDS, 1213 new ArrayBlockingQueue<Runnable>(10)); 1214 try (PoolCleaner cleaner = cleaner(p)) { 1215 assertNullTaskSubmissionThrowsNullPointerException(p); 1216 } 1217 } 1218 1219 /** 1220 * setCorePoolSize of negative value throws IllegalArgumentException 1221 */ testCorePoolSizeIllegalArgumentException()1222 public void testCorePoolSizeIllegalArgumentException() { 1223 final ThreadPoolExecutor p = 1224 new ThreadPoolExecutor(1, 2, 1225 LONG_DELAY_MS, MILLISECONDS, 1226 new ArrayBlockingQueue<Runnable>(10)); 1227 try (PoolCleaner cleaner = cleaner(p)) { 1228 try { 1229 p.setCorePoolSize(-1); 1230 shouldThrow(); 1231 } catch (IllegalArgumentException success) {} 1232 } 1233 } 1234 1235 /** 1236 * setMaximumPoolSize(int) throws IllegalArgumentException if 1237 * given a value less the core pool size 1238 */ testMaximumPoolSizeIllegalArgumentException()1239 public void testMaximumPoolSizeIllegalArgumentException() { 1240 final ThreadPoolExecutor p = 1241 new ThreadPoolExecutor(2, 3, 1242 LONG_DELAY_MS, MILLISECONDS, 1243 new ArrayBlockingQueue<Runnable>(10)); 1244 try (PoolCleaner cleaner = cleaner(p)) { 1245 try { 1246 p.setMaximumPoolSize(1); 1247 shouldThrow(); 1248 } catch (IllegalArgumentException success) {} 1249 } 1250 } 1251 1252 /** 1253 * setMaximumPoolSize throws IllegalArgumentException 1254 * if given a negative value 1255 */ testMaximumPoolSizeIllegalArgumentException2()1256 public void testMaximumPoolSizeIllegalArgumentException2() { 1257 final ThreadPoolExecutor p = 1258 new ThreadPoolExecutor(2, 3, 1259 LONG_DELAY_MS, MILLISECONDS, 1260 new ArrayBlockingQueue<Runnable>(10)); 1261 try (PoolCleaner cleaner = cleaner(p)) { 1262 try { 1263 p.setMaximumPoolSize(-1); 1264 shouldThrow(); 1265 } catch (IllegalArgumentException success) {} 1266 } 1267 } 1268 1269 /** 1270 * Configuration changes that allow core pool size greater than 1271 * max pool size result in IllegalArgumentException. 1272 */ testPoolSizeInvariants()1273 public void testPoolSizeInvariants() { 1274 final ThreadPoolExecutor p = 1275 new ThreadPoolExecutor(1, 1, 1276 LONG_DELAY_MS, MILLISECONDS, 1277 new ArrayBlockingQueue<Runnable>(10)); 1278 try (PoolCleaner cleaner = cleaner(p)) { 1279 for (int s = 1; s < 5; s++) { 1280 p.setMaximumPoolSize(s); 1281 p.setCorePoolSize(s); 1282 try { 1283 p.setMaximumPoolSize(s - 1); 1284 shouldThrow(); 1285 } catch (IllegalArgumentException success) {} 1286 assertEquals(s, p.getCorePoolSize()); 1287 assertEquals(s, p.getMaximumPoolSize()); 1288 try { 1289 p.setCorePoolSize(s + 1); 1290 shouldThrow(); 1291 } catch (IllegalArgumentException success) {} 1292 assertEquals(s, p.getCorePoolSize()); 1293 assertEquals(s, p.getMaximumPoolSize()); 1294 } 1295 } 1296 } 1297 1298 /** 1299 * setKeepAliveTime throws IllegalArgumentException 1300 * when given a negative value 1301 */ testKeepAliveTimeIllegalArgumentException()1302 public void testKeepAliveTimeIllegalArgumentException() { 1303 final ThreadPoolExecutor p = 1304 new ThreadPoolExecutor(2, 3, 1305 LONG_DELAY_MS, MILLISECONDS, 1306 new ArrayBlockingQueue<Runnable>(10)); 1307 try (PoolCleaner cleaner = cleaner(p)) { 1308 try { 1309 p.setKeepAliveTime(-1, MILLISECONDS); 1310 shouldThrow(); 1311 } catch (IllegalArgumentException success) {} 1312 } 1313 } 1314 1315 /** 1316 * terminated() is called on termination 1317 */ testTerminated()1318 public void testTerminated() { 1319 ExtendedTPE p = new ExtendedTPE(); 1320 try (PoolCleaner cleaner = cleaner(p)) { 1321 try { p.shutdown(); } catch (SecurityException ok) { return; } 1322 assertTrue(p.terminatedCalled()); 1323 assertTrue(p.isShutdown()); 1324 } 1325 } 1326 1327 /** 1328 * beforeExecute and afterExecute are called when executing task 1329 */ testBeforeAfter()1330 public void testBeforeAfter() throws InterruptedException { 1331 ExtendedTPE p = new ExtendedTPE(); 1332 try (PoolCleaner cleaner = cleaner(p)) { 1333 final CountDownLatch done = new CountDownLatch(1); 1334 p.execute(new CheckedRunnable() { 1335 public void realRun() { 1336 done.countDown(); 1337 }}); 1338 await(p.afterCalled); 1339 assertEquals(0, done.getCount()); 1340 assertTrue(p.afterCalled()); 1341 assertTrue(p.beforeCalled()); 1342 } 1343 } 1344 1345 /** 1346 * completed submit of callable returns result 1347 */ testSubmitCallable()1348 public void testSubmitCallable() throws Exception { 1349 final ExecutorService e = 1350 new ThreadPoolExecutor(2, 2, 1351 LONG_DELAY_MS, MILLISECONDS, 1352 new ArrayBlockingQueue<Runnable>(10)); 1353 try (PoolCleaner cleaner = cleaner(e)) { 1354 Future<String> future = e.submit(new StringTask()); 1355 String result = future.get(); 1356 assertSame(TEST_STRING, result); 1357 } 1358 } 1359 1360 /** 1361 * completed submit of runnable returns successfully 1362 */ testSubmitRunnable()1363 public void testSubmitRunnable() throws Exception { 1364 final ExecutorService e = 1365 new ThreadPoolExecutor(2, 2, 1366 LONG_DELAY_MS, MILLISECONDS, 1367 new ArrayBlockingQueue<Runnable>(10)); 1368 try (PoolCleaner cleaner = cleaner(e)) { 1369 Future<?> future = e.submit(new NoOpRunnable()); 1370 future.get(); 1371 assertTrue(future.isDone()); 1372 } 1373 } 1374 1375 /** 1376 * completed submit of (runnable, result) returns result 1377 */ testSubmitRunnable2()1378 public void testSubmitRunnable2() throws Exception { 1379 final ExecutorService e = 1380 new ThreadPoolExecutor(2, 2, 1381 LONG_DELAY_MS, MILLISECONDS, 1382 new ArrayBlockingQueue<Runnable>(10)); 1383 try (PoolCleaner cleaner = cleaner(e)) { 1384 Future<String> future = e.submit(new NoOpRunnable(), TEST_STRING); 1385 String result = future.get(); 1386 assertSame(TEST_STRING, result); 1387 } 1388 } 1389 1390 /** 1391 * invokeAny(null) throws NPE 1392 */ testInvokeAny1()1393 public void testInvokeAny1() throws Exception { 1394 final ExecutorService e = 1395 new ThreadPoolExecutor(2, 2, 1396 LONG_DELAY_MS, MILLISECONDS, 1397 new ArrayBlockingQueue<Runnable>(10)); 1398 try (PoolCleaner cleaner = cleaner(e)) { 1399 try { 1400 e.invokeAny(null); 1401 shouldThrow(); 1402 } catch (NullPointerException success) {} 1403 } 1404 } 1405 1406 /** 1407 * invokeAny(empty collection) throws IllegalArgumentException 1408 */ testInvokeAny2()1409 public void testInvokeAny2() throws Exception { 1410 final ExecutorService e = 1411 new ThreadPoolExecutor(2, 2, 1412 LONG_DELAY_MS, MILLISECONDS, 1413 new ArrayBlockingQueue<Runnable>(10)); 1414 try (PoolCleaner cleaner = cleaner(e)) { 1415 try { 1416 e.invokeAny(new ArrayList<Callable<String>>()); 1417 shouldThrow(); 1418 } catch (IllegalArgumentException success) {} 1419 } 1420 } 1421 1422 /** 1423 * invokeAny(c) throws NPE if c has null elements 1424 */ testInvokeAny3()1425 public void testInvokeAny3() throws Exception { 1426 final CountDownLatch latch = new CountDownLatch(1); 1427 final ExecutorService e = 1428 new ThreadPoolExecutor(2, 2, 1429 LONG_DELAY_MS, MILLISECONDS, 1430 new ArrayBlockingQueue<Runnable>(10)); 1431 try (PoolCleaner cleaner = cleaner(e)) { 1432 List<Callable<String>> l = new ArrayList<>(); 1433 l.add(latchAwaitingStringTask(latch)); 1434 l.add(null); 1435 try { 1436 e.invokeAny(l); 1437 shouldThrow(); 1438 } catch (NullPointerException success) {} 1439 latch.countDown(); 1440 } 1441 } 1442 1443 /** 1444 * invokeAny(c) throws ExecutionException if no task completes 1445 */ testInvokeAny4()1446 public void testInvokeAny4() throws Exception { 1447 final ExecutorService e = 1448 new ThreadPoolExecutor(2, 2, 1449 LONG_DELAY_MS, MILLISECONDS, 1450 new ArrayBlockingQueue<Runnable>(10)); 1451 try (PoolCleaner cleaner = cleaner(e)) { 1452 List<Callable<String>> l = new ArrayList<>(); 1453 l.add(new NPETask()); 1454 try { 1455 e.invokeAny(l); 1456 shouldThrow(); 1457 } catch (ExecutionException success) { 1458 assertTrue(success.getCause() instanceof NullPointerException); 1459 } 1460 } 1461 } 1462 1463 /** 1464 * invokeAny(c) returns result of some task 1465 */ testInvokeAny5()1466 public void testInvokeAny5() throws Exception { 1467 final ExecutorService e = 1468 new ThreadPoolExecutor(2, 2, 1469 LONG_DELAY_MS, MILLISECONDS, 1470 new ArrayBlockingQueue<Runnable>(10)); 1471 try (PoolCleaner cleaner = cleaner(e)) { 1472 List<Callable<String>> l = new ArrayList<>(); 1473 l.add(new StringTask()); 1474 l.add(new StringTask()); 1475 String result = e.invokeAny(l); 1476 assertSame(TEST_STRING, result); 1477 } 1478 } 1479 1480 /** 1481 * invokeAll(null) throws NPE 1482 */ testInvokeAll1()1483 public void testInvokeAll1() throws Exception { 1484 final ExecutorService e = 1485 new ThreadPoolExecutor(2, 2, 1486 LONG_DELAY_MS, MILLISECONDS, 1487 new ArrayBlockingQueue<Runnable>(10)); 1488 try (PoolCleaner cleaner = cleaner(e)) { 1489 try { 1490 e.invokeAll(null); 1491 shouldThrow(); 1492 } catch (NullPointerException success) {} 1493 } 1494 } 1495 1496 /** 1497 * invokeAll(empty collection) returns empty list 1498 */ testInvokeAll2()1499 public void testInvokeAll2() throws InterruptedException { 1500 final ExecutorService e = 1501 new ThreadPoolExecutor(2, 2, 1502 LONG_DELAY_MS, MILLISECONDS, 1503 new ArrayBlockingQueue<Runnable>(10)); 1504 final Collection<Callable<String>> emptyCollection 1505 = Collections.emptyList(); 1506 try (PoolCleaner cleaner = cleaner(e)) { 1507 List<Future<String>> r = e.invokeAll(emptyCollection); 1508 assertTrue(r.isEmpty()); 1509 } 1510 } 1511 1512 /** 1513 * invokeAll(c) throws NPE if c has null elements 1514 */ testInvokeAll3()1515 public void testInvokeAll3() throws Exception { 1516 final ExecutorService e = 1517 new ThreadPoolExecutor(2, 2, 1518 LONG_DELAY_MS, MILLISECONDS, 1519 new ArrayBlockingQueue<Runnable>(10)); 1520 try (PoolCleaner cleaner = cleaner(e)) { 1521 List<Callable<String>> l = new ArrayList<>(); 1522 l.add(new StringTask()); 1523 l.add(null); 1524 try { 1525 e.invokeAll(l); 1526 shouldThrow(); 1527 } catch (NullPointerException success) {} 1528 } 1529 } 1530 1531 /** 1532 * get of element of invokeAll(c) throws exception on failed task 1533 */ testInvokeAll4()1534 public void testInvokeAll4() throws Exception { 1535 final ExecutorService e = 1536 new ThreadPoolExecutor(2, 2, 1537 LONG_DELAY_MS, MILLISECONDS, 1538 new ArrayBlockingQueue<Runnable>(10)); 1539 try (PoolCleaner cleaner = cleaner(e)) { 1540 List<Callable<String>> l = new ArrayList<>(); 1541 l.add(new NPETask()); 1542 List<Future<String>> futures = e.invokeAll(l); 1543 assertEquals(1, futures.size()); 1544 try { 1545 futures.get(0).get(); 1546 shouldThrow(); 1547 } catch (ExecutionException success) { 1548 assertTrue(success.getCause() instanceof NullPointerException); 1549 } 1550 } 1551 } 1552 1553 /** 1554 * invokeAll(c) returns results of all completed tasks 1555 */ testInvokeAll5()1556 public void testInvokeAll5() throws Exception { 1557 final ExecutorService e = 1558 new ThreadPoolExecutor(2, 2, 1559 LONG_DELAY_MS, MILLISECONDS, 1560 new ArrayBlockingQueue<Runnable>(10)); 1561 try (PoolCleaner cleaner = cleaner(e)) { 1562 List<Callable<String>> l = new ArrayList<>(); 1563 l.add(new StringTask()); 1564 l.add(new StringTask()); 1565 List<Future<String>> futures = e.invokeAll(l); 1566 assertEquals(2, futures.size()); 1567 for (Future<String> future : futures) 1568 assertSame(TEST_STRING, future.get()); 1569 } 1570 } 1571 1572 /** 1573 * timed invokeAny(null) throws NPE 1574 */ testTimedInvokeAny1()1575 public void testTimedInvokeAny1() throws Exception { 1576 final ExecutorService e = 1577 new ThreadPoolExecutor(2, 2, 1578 LONG_DELAY_MS, MILLISECONDS, 1579 new ArrayBlockingQueue<Runnable>(10)); 1580 try (PoolCleaner cleaner = cleaner(e)) { 1581 try { 1582 e.invokeAny(null, randomTimeout(), randomTimeUnit()); 1583 shouldThrow(); 1584 } catch (NullPointerException success) {} 1585 } 1586 } 1587 1588 /** 1589 * timed invokeAny(,,null) throws NPE 1590 */ testTimedInvokeAnyNullTimeUnit()1591 public void testTimedInvokeAnyNullTimeUnit() throws Exception { 1592 final ExecutorService e = 1593 new ThreadPoolExecutor(2, 2, 1594 LONG_DELAY_MS, MILLISECONDS, 1595 new ArrayBlockingQueue<Runnable>(10)); 1596 try (PoolCleaner cleaner = cleaner(e)) { 1597 List<Callable<String>> l = new ArrayList<>(); 1598 l.add(new StringTask()); 1599 try { 1600 e.invokeAny(l, randomTimeout(), null); 1601 shouldThrow(); 1602 } catch (NullPointerException success) {} 1603 } 1604 } 1605 1606 /** 1607 * timed invokeAny(empty collection) throws IllegalArgumentException 1608 */ testTimedInvokeAny2()1609 public void testTimedInvokeAny2() throws Exception { 1610 final ExecutorService e = 1611 new ThreadPoolExecutor(2, 2, 1612 LONG_DELAY_MS, MILLISECONDS, 1613 new ArrayBlockingQueue<Runnable>(10)); 1614 try (PoolCleaner cleaner = cleaner(e)) { 1615 try { 1616 e.invokeAny(new ArrayList<Callable<String>>(), 1617 randomTimeout(), randomTimeUnit()); 1618 shouldThrow(); 1619 } catch (IllegalArgumentException success) {} 1620 } 1621 } 1622 1623 /** 1624 * timed invokeAny(c) throws NullPointerException if c has null elements 1625 */ testTimedInvokeAny3()1626 public void testTimedInvokeAny3() throws Exception { 1627 final CountDownLatch latch = new CountDownLatch(1); 1628 final ExecutorService e = 1629 new ThreadPoolExecutor(2, 2, 1630 LONG_DELAY_MS, MILLISECONDS, 1631 new ArrayBlockingQueue<Runnable>(10)); 1632 try (PoolCleaner cleaner = cleaner(e)) { 1633 List<Callable<String>> l = new ArrayList<>(); 1634 l.add(latchAwaitingStringTask(latch)); 1635 l.add(null); 1636 try { 1637 e.invokeAny(l, randomTimeout(), randomTimeUnit()); 1638 shouldThrow(); 1639 } catch (NullPointerException success) {} 1640 latch.countDown(); 1641 } 1642 } 1643 1644 /** 1645 * timed invokeAny(c) throws ExecutionException if no task completes 1646 */ testTimedInvokeAny4()1647 public void testTimedInvokeAny4() throws Exception { 1648 final ExecutorService e = 1649 new ThreadPoolExecutor(2, 2, 1650 LONG_DELAY_MS, MILLISECONDS, 1651 new ArrayBlockingQueue<Runnable>(10)); 1652 try (PoolCleaner cleaner = cleaner(e)) { 1653 long startTime = System.nanoTime(); 1654 List<Callable<String>> l = new ArrayList<>(); 1655 l.add(new NPETask()); 1656 try { 1657 e.invokeAny(l, LONG_DELAY_MS, MILLISECONDS); 1658 shouldThrow(); 1659 } catch (ExecutionException success) { 1660 assertTrue(success.getCause() instanceof NullPointerException); 1661 } 1662 assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS); 1663 } 1664 } 1665 1666 /** 1667 * timed invokeAny(c) returns result of some task 1668 */ 1669 public void testTimedInvokeAny5() throws Exception { 1670 final ExecutorService e = 1671 new ThreadPoolExecutor(2, 2, 1672 LONG_DELAY_MS, MILLISECONDS, 1673 new ArrayBlockingQueue<Runnable>(10)); 1674 try (PoolCleaner cleaner = cleaner(e)) { 1675 long startTime = System.nanoTime(); 1676 List<Callable<String>> l = new ArrayList<>(); 1677 l.add(new StringTask()); 1678 l.add(new StringTask()); 1679 String result = e.invokeAny(l, LONG_DELAY_MS, MILLISECONDS); 1680 assertSame(TEST_STRING, result); 1681 assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS); 1682 } 1683 } 1684 1685 /** 1686 * timed invokeAll(null) throws NPE 1687 */ 1688 public void testTimedInvokeAll1() throws Exception { 1689 final ExecutorService e = 1690 new ThreadPoolExecutor(2, 2, 1691 LONG_DELAY_MS, MILLISECONDS, 1692 new ArrayBlockingQueue<Runnable>(10)); 1693 try (PoolCleaner cleaner = cleaner(e)) { 1694 try { 1695 e.invokeAll(null, randomTimeout(), randomTimeUnit()); 1696 shouldThrow(); 1697 } catch (NullPointerException success) {} 1698 } 1699 } 1700 1701 /** 1702 * timed invokeAll(,,null) throws NPE 1703 */ 1704 public void testTimedInvokeAllNullTimeUnit() throws Exception { 1705 final ExecutorService e = 1706 new ThreadPoolExecutor(2, 2, 1707 LONG_DELAY_MS, MILLISECONDS, 1708 new ArrayBlockingQueue<Runnable>(10)); 1709 try (PoolCleaner cleaner = cleaner(e)) { 1710 List<Callable<String>> l = new ArrayList<>(); 1711 l.add(new StringTask()); 1712 try { 1713 e.invokeAll(l, randomTimeout(), null); 1714 shouldThrow(); 1715 } catch (NullPointerException success) {} 1716 } 1717 } 1718 1719 /** 1720 * timed invokeAll(empty collection) returns empty list 1721 */ 1722 public void testTimedInvokeAll2() throws InterruptedException { 1723 final ExecutorService e = 1724 new ThreadPoolExecutor(2, 2, 1725 LONG_DELAY_MS, MILLISECONDS, 1726 new ArrayBlockingQueue<Runnable>(10)); 1727 final Collection<Callable<String>> emptyCollection 1728 = Collections.emptyList(); 1729 try (PoolCleaner cleaner = cleaner(e)) { 1730 List<Future<String>> r = 1731 e.invokeAll(emptyCollection, randomTimeout(), randomTimeUnit()); 1732 assertTrue(r.isEmpty()); 1733 } 1734 } 1735 1736 /** 1737 * timed invokeAll(c) throws NPE if c has null elements 1738 */ 1739 public void testTimedInvokeAll3() throws Exception { 1740 final ExecutorService e = 1741 new ThreadPoolExecutor(2, 2, 1742 LONG_DELAY_MS, MILLISECONDS, 1743 new ArrayBlockingQueue<Runnable>(10)); 1744 try (PoolCleaner cleaner = cleaner(e)) { 1745 List<Callable<String>> l = new ArrayList<>(); 1746 l.add(new StringTask()); 1747 l.add(null); 1748 try { 1749 e.invokeAll(l, randomTimeout(), randomTimeUnit()); 1750 shouldThrow(); 1751 } catch (NullPointerException success) {} 1752 } 1753 } 1754 1755 /** 1756 * get of element of invokeAll(c) throws exception on failed task 1757 */ 1758 public void testTimedInvokeAll4() throws Exception { 1759 final ExecutorService e = 1760 new ThreadPoolExecutor(2, 2, 1761 LONG_DELAY_MS, MILLISECONDS, 1762 new ArrayBlockingQueue<Runnable>(10)); 1763 try (PoolCleaner cleaner = cleaner(e)) { 1764 List<Callable<String>> l = new ArrayList<>(); 1765 l.add(new NPETask()); 1766 List<Future<String>> futures = 1767 e.invokeAll(l, LONG_DELAY_MS, MILLISECONDS); 1768 assertEquals(1, futures.size()); 1769 try { 1770 futures.get(0).get(); 1771 shouldThrow(); 1772 } catch (ExecutionException success) { 1773 assertTrue(success.getCause() instanceof NullPointerException); 1774 } 1775 } 1776 } 1777 1778 /** 1779 * timed invokeAll(c) returns results of all completed tasks 1780 */ 1781 public void testTimedInvokeAll5() throws Exception { 1782 final ExecutorService e = 1783 new ThreadPoolExecutor(2, 2, 1784 LONG_DELAY_MS, MILLISECONDS, 1785 new ArrayBlockingQueue<Runnable>(10)); 1786 try (PoolCleaner cleaner = cleaner(e)) { 1787 List<Callable<String>> l = new ArrayList<>(); 1788 l.add(new StringTask()); 1789 l.add(new StringTask()); 1790 List<Future<String>> futures = 1791 e.invokeAll(l, LONG_DELAY_MS, MILLISECONDS); 1792 assertEquals(2, futures.size()); 1793 for (Future<String> future : futures) 1794 assertSame(TEST_STRING, future.get()); 1795 } 1796 } 1797 1798 /** 1799 * timed invokeAll(c) cancels tasks not completed by timeout 1800 */ 1801 public void testTimedInvokeAll6() throws Exception { 1802 for (long timeout = timeoutMillis();;) { 1803 final CountDownLatch done = new CountDownLatch(1); 1804 final Callable<String> waiter = new CheckedCallable<>() { 1805 public String realCall() { 1806 try { done.await(LONG_DELAY_MS, MILLISECONDS); } 1807 catch (InterruptedException ok) {} 1808 return "1"; }}; 1809 final ExecutorService p = 1810 new ThreadPoolExecutor(2, 2, 1811 LONG_DELAY_MS, MILLISECONDS, 1812 new ArrayBlockingQueue<Runnable>(10)); 1813 try (PoolCleaner cleaner = cleaner(p, done)) { 1814 List<Callable<String>> tasks = new ArrayList<>(); 1815 tasks.add(new StringTask("0")); 1816 tasks.add(waiter); 1817 tasks.add(new StringTask("2")); 1818 long startTime = System.nanoTime(); 1819 List<Future<String>> futures = 1820 p.invokeAll(tasks, timeout, MILLISECONDS); 1821 assertEquals(tasks.size(), futures.size()); 1822 assertTrue(millisElapsedSince(startTime) >= timeout); 1823 for (Future<?> future : futures) 1824 assertTrue(future.isDone()); 1825 assertTrue(futures.get(1).isCancelled()); 1826 try { 1827 assertEquals("0", futures.get(0).get()); 1828 assertEquals("2", futures.get(2).get()); 1829 break; 1830 } catch (CancellationException retryWithLongerTimeout) { 1831 timeout *= 2; 1832 if (timeout >= LONG_DELAY_MS / 2) 1833 fail("expected exactly one task to be cancelled"); 1834 } 1835 } 1836 } 1837 } 1838 1839 /** 1840 * Execution continues if there is at least one thread even if 1841 * thread factory fails to create more 1842 */ 1843 public void testFailingThreadFactory() throws InterruptedException { 1844 final ExecutorService e = 1845 new ThreadPoolExecutor(100, 100, 1846 LONG_DELAY_MS, MILLISECONDS, 1847 new LinkedBlockingQueue<Runnable>(), 1848 new FailingThreadFactory()); 1849 try (PoolCleaner cleaner = cleaner(e)) { 1850 final int TASKS = 100; 1851 final CountDownLatch done = new CountDownLatch(TASKS); 1852 for (int k = 0; k < TASKS; ++k) 1853 e.execute(new CheckedRunnable() { 1854 public void realRun() { 1855 done.countDown(); 1856 }}); 1857 await(done); 1858 } 1859 } 1860 1861 /** 1862 * allowsCoreThreadTimeOut is by default false. 1863 */ 1864 public void testAllowsCoreThreadTimeOut() { 1865 final ThreadPoolExecutor p = 1866 new ThreadPoolExecutor(2, 2, 1867 1000, MILLISECONDS, 1868 new ArrayBlockingQueue<Runnable>(10)); 1869 try (PoolCleaner cleaner = cleaner(p)) { 1870 assertFalse(p.allowsCoreThreadTimeOut()); 1871 } 1872 } 1873 1874 /** 1875 * allowCoreThreadTimeOut(true) causes idle threads to time out 1876 */ 1877 public void testAllowCoreThreadTimeOut_true() throws Exception { 1878 long keepAliveTime = timeoutMillis(); 1879 final ThreadPoolExecutor p = 1880 new ThreadPoolExecutor(2, 10, 1881 keepAliveTime, MILLISECONDS, 1882 new ArrayBlockingQueue<Runnable>(10)); 1883 try (PoolCleaner cleaner = cleaner(p)) { 1884 final CountDownLatch threadStarted = new CountDownLatch(1); 1885 p.allowCoreThreadTimeOut(true); 1886 p.execute(new CheckedRunnable() { 1887 public void realRun() { 1888 threadStarted.countDown(); 1889 assertEquals(1, p.getPoolSize()); 1890 }}); 1891 await(threadStarted); 1892 delay(keepAliveTime); 1893 long startTime = System.nanoTime(); 1894 while (p.getPoolSize() > 0 1895 && millisElapsedSince(startTime) < LONG_DELAY_MS) 1896 Thread.yield(); 1897 assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS); 1898 assertEquals(0, p.getPoolSize()); 1899 } 1900 } 1901 1902 /** 1903 * allowCoreThreadTimeOut(false) causes idle threads not to time out 1904 */ 1905 public void testAllowCoreThreadTimeOut_false() throws Exception { 1906 long keepAliveTime = timeoutMillis(); 1907 final ThreadPoolExecutor p = 1908 new ThreadPoolExecutor(2, 10, 1909 keepAliveTime, MILLISECONDS, 1910 new ArrayBlockingQueue<Runnable>(10)); 1911 try (PoolCleaner cleaner = cleaner(p)) { 1912 final CountDownLatch threadStarted = new CountDownLatch(1); 1913 p.allowCoreThreadTimeOut(false); 1914 p.execute(new CheckedRunnable() { 1915 public void realRun() throws InterruptedException { 1916 threadStarted.countDown(); 1917 assertTrue(p.getPoolSize() >= 1); 1918 }}); 1919 delay(2 * keepAliveTime); 1920 assertTrue(p.getPoolSize() >= 1); 1921 } 1922 } 1923 1924 /** 1925 * execute allows the same task to be submitted multiple times, even 1926 * if rejected 1927 */ 1928 public void testRejectedRecycledTask() throws InterruptedException { 1929 final int nTasks = 1000; 1930 final CountDownLatch done = new CountDownLatch(nTasks); 1931 final Runnable recycledTask = new Runnable() { 1932 public void run() { 1933 done.countDown(); 1934 }}; 1935 final ThreadPoolExecutor p = 1936 new ThreadPoolExecutor(1, 30, 1937 60, SECONDS, 1938 new ArrayBlockingQueue<Runnable>(30)); 1939 try (PoolCleaner cleaner = cleaner(p)) { 1940 for (int i = 0; i < nTasks; ++i) { 1941 for (;;) { 1942 try { 1943 p.execute(recycledTask); 1944 break; 1945 } 1946 catch (RejectedExecutionException ignore) {} 1947 } 1948 } 1949 // enough time to run all tasks 1950 await(done, nTasks * SHORT_DELAY_MS); 1951 } 1952 } 1953 1954 /** 1955 * get(cancelled task) throws CancellationException 1956 */ 1957 public void testGet_cancelled() throws Exception { 1958 final CountDownLatch done = new CountDownLatch(1); 1959 final ExecutorService e = 1960 new ThreadPoolExecutor(1, 1, 1961 LONG_DELAY_MS, MILLISECONDS, 1962 new LinkedBlockingQueue<Runnable>()); 1963 try (PoolCleaner cleaner = cleaner(e, done)) { 1964 final CountDownLatch blockerStarted = new CountDownLatch(1); 1965 final List<Future<?>> futures = new ArrayList<>(); 1966 for (int i = 0; i < 2; i++) { 1967 Runnable r = new CheckedRunnable() { public void realRun() 1968 throws Throwable { 1969 blockerStarted.countDown(); 1970 assertTrue(done.await(2 * LONG_DELAY_MS, MILLISECONDS)); 1971 }}; 1972 futures.add(e.submit(r)); 1973 } 1974 await(blockerStarted); 1975 for (Future<?> future : futures) future.cancel(false); 1976 for (Future<?> future : futures) { 1977 try { 1978 future.get(); 1979 shouldThrow(); 1980 } catch (CancellationException success) {} 1981 try { 1982 future.get(LONG_DELAY_MS, MILLISECONDS); 1983 shouldThrow(); 1984 } catch (CancellationException success) {} 1985 assertTrue(future.isCancelled()); 1986 assertTrue(future.isDone()); 1987 } 1988 } 1989 } 1990 1991 /** Directly test simple ThreadPoolExecutor RejectedExecutionHandlers. */ 1992 public void testStandardRejectedExecutionHandlers() { 1993 final ThreadPoolExecutor p = 1994 new ThreadPoolExecutor(1, 1, 1, SECONDS, 1995 new ArrayBlockingQueue<Runnable>(1)); 1996 final AtomicReference<Thread> thread = new AtomicReference<>(); 1997 final Runnable r = new Runnable() { public void run() { 1998 thread.set(Thread.currentThread()); }}; 1999 2000 try { 2001 new AbortPolicy().rejectedExecution(r, p); 2002 shouldThrow(); 2003 } catch (RejectedExecutionException success) {} 2004 assertNull(thread.get()); 2005 2006 new DiscardPolicy().rejectedExecution(r, p); 2007 assertNull(thread.get()); 2008 2009 new CallerRunsPolicy().rejectedExecution(r, p); 2010 assertSame(Thread.currentThread(), thread.get()); 2011 2012 // check that pool was not perturbed by handlers 2013 assertTrue(p.getRejectedExecutionHandler() instanceof AbortPolicy); 2014 assertEquals(0, p.getTaskCount()); 2015 assertTrue(p.getQueue().isEmpty()); 2016 } 2017 2018 public void testThreadFactoryReturnsTerminatedThread_shouldThrow() { 2019 if (!testImplementationDetails) 2020 return; 2021 2022 ThreadFactory returnsTerminatedThread = runnableIgnored -> { 2023 Thread thread = new Thread(() -> {}); 2024 thread.start(); 2025 try { thread.join(); } 2026 catch (InterruptedException ex) { throw new Error(ex); } 2027 return thread; 2028 }; 2029 ThreadPoolExecutor p = 2030 new ThreadPoolExecutor(1, 1, 1, SECONDS, 2031 new ArrayBlockingQueue<Runnable>(1), 2032 returnsTerminatedThread); 2033 try (PoolCleaner cleaner = cleaner(p)) { 2034 assertThrows(IllegalThreadStateException.class, 2035 () -> p.execute(() -> {})); 2036 } 2037 } 2038 2039 public void testThreadFactoryReturnsStartedThread_shouldThrow() { 2040 if (!testImplementationDetails) 2041 return; 2042 2043 CountDownLatch latch = new CountDownLatch(1); 2044 Runnable awaitLatch = () -> { 2045 try { latch.await(); } 2046 catch (InterruptedException ex) { throw new Error(ex); }}; 2047 ThreadFactory returnsStartedThread = runnable -> { 2048 Thread thread = new Thread(awaitLatch); 2049 thread.start(); 2050 return thread; 2051 }; 2052 ThreadPoolExecutor p = 2053 new ThreadPoolExecutor(1, 1, 1, SECONDS, 2054 new ArrayBlockingQueue<Runnable>(1), 2055 returnsStartedThread); 2056 try (PoolCleaner cleaner = cleaner(p)) { 2057 assertThrows(IllegalThreadStateException.class, 2058 () -> p.execute(() -> {})); 2059 latch.countDown(); 2060 } 2061 } 2062 2063 } 2064