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 */ 33 34 import static java.util.concurrent.TimeUnit.MILLISECONDS; 35 import static java.util.concurrent.TimeUnit.NANOSECONDS; 36 37 import java.security.PrivilegedAction; 38 import java.security.PrivilegedExceptionAction; 39 import java.util.ArrayList; 40 import java.util.Collection; 41 import java.util.Collections; 42 import java.util.List; 43 import java.util.concurrent.Callable; 44 import java.util.concurrent.CountDownLatch; 45 import java.util.concurrent.ExecutionException; 46 import java.util.concurrent.Executors; 47 import java.util.concurrent.ExecutorService; 48 import java.util.concurrent.ForkJoinPool; 49 import java.util.concurrent.ForkJoinTask; 50 import java.util.concurrent.ForkJoinWorkerThread; 51 import java.util.concurrent.Future; 52 import java.util.concurrent.RecursiveTask; 53 import java.util.concurrent.RejectedExecutionException; 54 import java.util.concurrent.atomic.AtomicBoolean; 55 import java.util.concurrent.atomic.AtomicInteger; 56 import java.util.concurrent.locks.ReentrantLock; 57 58 import junit.framework.Test; 59 import junit.framework.TestSuite; 60 61 public class ForkJoinPoolTest extends JSR166TestCase { 62 public static void main(String[] args) { 63 main(suite(), args); 64 } 65 66 public static Test suite() { 67 return new TestSuite(ForkJoinPoolTest.class); 68 } 69 70 /* 71 * Testing coverage notes: 72 * 73 * 1. shutdown and related methods are tested via super.joinPool. 74 * 75 * 2. newTaskFor and adapters are tested in submit/invoke tests 76 * 77 * 3. We cannot portably test monitoring methods such as 78 * getStealCount() since they rely ultimately on random task 79 * stealing that may cause tasks not to be stolen/propagated 80 * across threads, especially on uniprocessors. 81 * 82 * 4. There are no independently testable ForkJoinWorkerThread 83 * methods, but they are covered here and in task tests. 84 */ 85 86 // Some classes to test extension and factory methods 87 88 static class MyError extends Error {} 89 90 // to test handlers 91 static class FailingFJWSubclass extends ForkJoinWorkerThread { 92 public FailingFJWSubclass(ForkJoinPool p) { super(p) ; } 93 protected void onStart() { super.onStart(); throw new MyError(); } 94 } 95 96 static class FailingThreadFactory 97 implements ForkJoinPool.ForkJoinWorkerThreadFactory { 98 final AtomicInteger calls = new AtomicInteger(0); 99 public ForkJoinWorkerThread newThread(ForkJoinPool p) { 100 if (calls.incrementAndGet() > 1) return null; 101 return new FailingFJWSubclass(p); 102 } 103 } 104 105 static class SubFJP extends ForkJoinPool { // to expose protected 106 SubFJP() { super(1); } 107 public int drainTasksTo(Collection<? super ForkJoinTask<?>> c) { 108 return super.drainTasksTo(c); 109 } 110 public ForkJoinTask<?> pollSubmission() { 111 return super.pollSubmission(); 112 } 113 } 114 115 static class ManagedLocker implements ForkJoinPool.ManagedBlocker { 116 final ReentrantLock lock; 117 boolean hasLock = false; 118 ManagedLocker(ReentrantLock lock) { this.lock = lock; } 119 public boolean block() { 120 if (!hasLock) 121 lock.lock(); 122 return true; 123 } 124 public boolean isReleasable() { 125 return hasLock || (hasLock = lock.tryLock()); 126 } 127 } 128 129 // A simple recursive task for testing 130 static final class FibTask extends RecursiveTask<Integer> { 131 final int number; 132 FibTask(int n) { number = n; } 133 protected Integer compute() { 134 int n = number; 135 if (n <= 1) 136 return n; 137 FibTask f1 = new FibTask(n - 1); 138 f1.fork(); 139 return new FibTask(n - 2).compute() + f1.join(); 140 } 141 } 142 143 // A failing task for testing 144 static final class FailingTask extends ForkJoinTask<Void> { 145 public final Void getRawResult() { return null; } 146 protected final void setRawResult(Void mustBeNull) { } 147 protected final boolean exec() { throw new Error(); } 148 FailingTask() {} 149 } 150 151 // Fib needlessly using locking to test ManagedBlockers 152 static final class LockingFibTask extends RecursiveTask<Integer> { 153 final int number; 154 final ManagedLocker locker; 155 final ReentrantLock lock; 156 LockingFibTask(int n, ManagedLocker locker, ReentrantLock lock) { 157 number = n; 158 this.locker = locker; 159 this.lock = lock; 160 } 161 protected Integer compute() { 162 int n; 163 LockingFibTask f1 = null; 164 LockingFibTask f2 = null; 165 locker.block(); 166 n = number; 167 if (n > 1) { 168 f1 = new LockingFibTask(n - 1, locker, lock); 169 f2 = new LockingFibTask(n - 2, locker, lock); 170 } 171 lock.unlock(); 172 if (n <= 1) 173 return n; 174 else { 175 f1.fork(); 176 return f2.compute() + f1.join(); 177 } 178 } 179 } 180 181 /** 182 * Successfully constructed pool reports default factory, 183 * parallelism and async mode policies, no active threads or 184 * tasks, and quiescent running state. 185 */ 186 public void testDefaultInitialState() { 187 ForkJoinPool p = new ForkJoinPool(1); 188 try (PoolCleaner cleaner = cleaner(p)) { 189 assertSame(ForkJoinPool.defaultForkJoinWorkerThreadFactory, 190 p.getFactory()); 191 assertFalse(p.getAsyncMode()); 192 assertEquals(0, p.getActiveThreadCount()); 193 assertEquals(0, p.getStealCount()); 194 assertEquals(0, p.getQueuedTaskCount()); 195 assertEquals(0, p.getQueuedSubmissionCount()); 196 assertFalse(p.hasQueuedSubmissions()); 197 assertFalse(p.isShutdown()); 198 assertFalse(p.isTerminating()); 199 assertFalse(p.isTerminated()); 200 } 201 } 202 203 /** 204 * Constructor throws if size argument is less than zero 205 */ 206 public void testConstructor1() { 207 try { 208 new ForkJoinPool(-1); 209 shouldThrow(); 210 } catch (IllegalArgumentException success) {} 211 } 212 213 /** 214 * Constructor throws if factory argument is null 215 */ 216 public void testConstructor2() { 217 try { 218 new ForkJoinPool(1, null, null, false); 219 shouldThrow(); 220 } catch (NullPointerException success) {} 221 } 222 223 /** 224 * getParallelism returns size set in constructor 225 */ 226 public void testGetParallelism() { 227 ForkJoinPool p = new ForkJoinPool(1); 228 try (PoolCleaner cleaner = cleaner(p)) { 229 assertEquals(1, p.getParallelism()); 230 } 231 } 232 233 /** 234 * getPoolSize returns number of started workers. 235 */ 236 public void testGetPoolSize() { 237 final CountDownLatch taskStarted = new CountDownLatch(1); 238 final CountDownLatch done = new CountDownLatch(1); 239 final ForkJoinPool p = new ForkJoinPool(1); 240 try (PoolCleaner cleaner = cleaner(p)) { 241 assertEquals(0, p.getActiveThreadCount()); 242 final Runnable task = new CheckedRunnable() { 243 public void realRun() throws InterruptedException { 244 taskStarted.countDown(); 245 assertEquals(1, p.getPoolSize()); 246 assertEquals(1, p.getActiveThreadCount()); 247 await(done); 248 }}; 249 Future<?> future = p.submit(task); 250 await(taskStarted); 251 assertEquals(1, p.getPoolSize()); 252 assertEquals(1, p.getActiveThreadCount()); 253 done.countDown(); 254 } 255 assertEquals(0, p.getPoolSize()); 256 assertEquals(0, p.getActiveThreadCount()); 257 } 258 259 /** 260 * awaitTermination on a non-shutdown pool times out 261 */ 262 public void testAwaitTermination_timesOut() throws InterruptedException { 263 ForkJoinPool p = new ForkJoinPool(1); 264 try (PoolCleaner cleaner = cleaner(p)) { 265 assertFalse(p.isTerminated()); 266 assertFalse(p.awaitTermination(Long.MIN_VALUE, NANOSECONDS)); 267 assertFalse(p.awaitTermination(Long.MIN_VALUE, MILLISECONDS)); 268 assertFalse(p.awaitTermination(-1L, NANOSECONDS)); 269 assertFalse(p.awaitTermination(-1L, MILLISECONDS)); 270 assertFalse(p.awaitTermination(randomExpiredTimeout(), 271 randomTimeUnit())); 272 long timeoutNanos = 999999L; 273 long startTime = System.nanoTime(); 274 assertFalse(p.awaitTermination(timeoutNanos, NANOSECONDS)); 275 assertTrue(System.nanoTime() - startTime >= timeoutNanos); 276 assertFalse(p.isTerminated()); 277 startTime = System.nanoTime(); 278 long timeoutMillis = timeoutMillis(); 279 assertFalse(p.awaitTermination(timeoutMillis, MILLISECONDS)); 280 assertTrue(millisElapsedSince(startTime) >= timeoutMillis); 281 assertFalse(p.isTerminated()); 282 p.shutdown(); 283 assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS)); 284 assertTrue(p.isTerminated()); 285 } 286 } 287 288 /** 289 * setUncaughtExceptionHandler changes handler for uncaught exceptions. 290 * 291 * Additionally tests: Overriding ForkJoinWorkerThread.onStart 292 * performs its defined action 293 */ 294 public void testSetUncaughtExceptionHandler() throws InterruptedException { 295 final CountDownLatch uehInvoked = new CountDownLatch(1); 296 final Thread.UncaughtExceptionHandler ueh = 297 new Thread.UncaughtExceptionHandler() { 298 public void uncaughtException(Thread t, Throwable e) { 299 threadAssertTrue(e instanceof MyError); 300 threadAssertTrue(t instanceof FailingFJWSubclass); 301 uehInvoked.countDown(); 302 }}; 303 ForkJoinPool p = new ForkJoinPool(1, new FailingThreadFactory(), 304 ueh, false); 305 try (PoolCleaner cleaner = cleaner(p)) { 306 assertSame(ueh, p.getUncaughtExceptionHandler()); 307 try { 308 p.execute(new FibTask(8)); 309 await(uehInvoked); 310 } finally { 311 p.shutdownNow(); // failure might have prevented processing task 312 } 313 } 314 } 315 316 /** 317 * After invoking a single task, isQuiescent eventually becomes 318 * true, at which time queues are empty, threads are not active, 319 * the task has completed successfully, and construction 320 * parameters continue to hold 321 */ 322 public void testIsQuiescent() throws Exception { 323 ForkJoinPool p = new ForkJoinPool(2); 324 try (PoolCleaner cleaner = cleaner(p)) { 325 assertTrue(p.isQuiescent()); 326 long startTime = System.nanoTime(); 327 FibTask f = new FibTask(20); 328 p.invoke(f); 329 assertSame(ForkJoinPool.defaultForkJoinWorkerThreadFactory, 330 p.getFactory()); 331 while (! p.isQuiescent()) { 332 if (millisElapsedSince(startTime) > LONG_DELAY_MS) 333 throw new AssertionError("timed out"); 334 assertFalse(p.getAsyncMode()); 335 assertFalse(p.isShutdown()); 336 assertFalse(p.isTerminating()); 337 assertFalse(p.isTerminated()); 338 Thread.yield(); 339 } 340 341 assertTrue(p.isQuiescent()); 342 assertFalse(p.getAsyncMode()); 343 assertEquals(0, p.getQueuedTaskCount()); 344 assertEquals(0, p.getQueuedSubmissionCount()); 345 assertFalse(p.hasQueuedSubmissions()); 346 while (p.getActiveThreadCount() != 0 347 && millisElapsedSince(startTime) < LONG_DELAY_MS) 348 Thread.yield(); 349 assertFalse(p.isShutdown()); 350 assertFalse(p.isTerminating()); 351 assertFalse(p.isTerminated()); 352 assertTrue(f.isDone()); 353 assertEquals(6765, (int) f.get()); 354 assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS); 355 } 356 } 357 358 /** 359 * Completed submit(ForkJoinTask) returns result 360 */ 361 public void testSubmitForkJoinTask() throws Throwable { 362 ForkJoinPool p = new ForkJoinPool(1); 363 try (PoolCleaner cleaner = cleaner(p)) { 364 ForkJoinTask<Integer> f = p.submit(new FibTask(8)); 365 assertEquals(21, (int) f.get()); 366 } 367 } 368 369 /** 370 * A task submitted after shutdown is rejected 371 */ 372 public void testSubmitAfterShutdown() { 373 ForkJoinPool p = new ForkJoinPool(1); 374 try (PoolCleaner cleaner = cleaner(p)) { 375 p.shutdown(); 376 assertTrue(p.isShutdown()); 377 try { 378 ForkJoinTask<Integer> unused = p.submit(new FibTask(8)); 379 shouldThrow(); 380 } catch (RejectedExecutionException success) {} 381 } 382 } 383 384 /** 385 * Pool maintains parallelism when using ManagedBlocker 386 */ 387 public void testBlockingForkJoinTask() throws Throwable { 388 ForkJoinPool p = new ForkJoinPool(4); 389 try { 390 ReentrantLock lock = new ReentrantLock(); 391 ManagedLocker locker = new ManagedLocker(lock); 392 ForkJoinTask<Integer> f = new LockingFibTask(20, locker, lock); 393 p.execute(f); 394 assertEquals(6765, (int) f.get()); 395 } finally { 396 p.shutdownNow(); // don't wait out shutdown 397 } 398 } 399 400 /** 401 * pollSubmission returns unexecuted submitted task, if present 402 */ 403 public void testPollSubmission() { 404 final CountDownLatch done = new CountDownLatch(1); 405 SubFJP p = new SubFJP(); 406 try (PoolCleaner cleaner = cleaner(p)) { 407 ForkJoinTask a = p.submit(awaiter(done)); 408 ForkJoinTask b = p.submit(awaiter(done)); 409 ForkJoinTask c = p.submit(awaiter(done)); 410 ForkJoinTask r = p.pollSubmission(); 411 assertTrue(r == a || r == b || r == c); 412 assertFalse(r.isDone()); 413 done.countDown(); 414 } 415 } 416 417 /** 418 * drainTasksTo transfers unexecuted submitted tasks, if present 419 */ 420 public void testDrainTasksTo() { 421 final CountDownLatch done = new CountDownLatch(1); 422 SubFJP p = new SubFJP(); 423 try (PoolCleaner cleaner = cleaner(p)) { 424 ForkJoinTask a = p.submit(awaiter(done)); 425 ForkJoinTask b = p.submit(awaiter(done)); 426 ForkJoinTask c = p.submit(awaiter(done)); 427 ArrayList<ForkJoinTask> al = new ArrayList(); 428 p.drainTasksTo(al); 429 assertTrue(al.size() > 0); 430 for (ForkJoinTask r : al) { 431 assertTrue(r == a || r == b || r == c); 432 assertFalse(r.isDone()); 433 } 434 done.countDown(); 435 } 436 } 437 438 // FJ Versions of AbstractExecutorService tests 439 440 /** 441 * execute(runnable) runs it to completion 442 */ 443 public void testExecuteRunnable() throws Throwable { 444 ExecutorService e = new ForkJoinPool(1); 445 try (PoolCleaner cleaner = cleaner(e)) { 446 final AtomicBoolean done = new AtomicBoolean(false); 447 Future<?> future = e.submit(new CheckedRunnable() { 448 public void realRun() { 449 done.set(true); 450 }}); 451 assertNull(future.get()); 452 assertNull(future.get(randomExpiredTimeout(), randomTimeUnit())); 453 assertTrue(done.get()); 454 assertTrue(future.isDone()); 455 assertFalse(future.isCancelled()); 456 } 457 } 458 459 /** 460 * Completed submit(callable) returns result 461 */ 462 public void testSubmitCallable() throws Throwable { 463 ExecutorService e = new ForkJoinPool(1); 464 try (PoolCleaner cleaner = cleaner(e)) { 465 Future<String> future = e.submit(new StringTask()); 466 assertSame(TEST_STRING, future.get()); 467 assertTrue(future.isDone()); 468 assertFalse(future.isCancelled()); 469 } 470 } 471 472 /** 473 * Completed submit(runnable) returns successfully 474 */ 475 public void testSubmitRunnable() throws Throwable { 476 ExecutorService e = new ForkJoinPool(1); 477 try (PoolCleaner cleaner = cleaner(e)) { 478 Future<?> future = e.submit(new NoOpRunnable()); 479 assertNull(future.get()); 480 assertTrue(future.isDone()); 481 assertFalse(future.isCancelled()); 482 } 483 } 484 485 /** 486 * Completed submit(runnable, result) returns result 487 */ 488 public void testSubmitRunnable2() throws Throwable { 489 ExecutorService e = new ForkJoinPool(1); 490 try (PoolCleaner cleaner = cleaner(e)) { 491 Future<String> future = e.submit(new NoOpRunnable(), TEST_STRING); 492 assertSame(TEST_STRING, future.get()); 493 assertTrue(future.isDone()); 494 assertFalse(future.isCancelled()); 495 } 496 } 497 498 /** 499 * A submitted privileged action runs to completion 500 */ 501 public void testSubmitPrivilegedAction() throws Exception { 502 final Callable callable = Executors.callable(new PrivilegedAction() { 503 public Object run() { return TEST_STRING; }}); 504 Runnable r = new CheckedRunnable() { 505 public void realRun() throws Exception { 506 ExecutorService e = new ForkJoinPool(1); 507 try (PoolCleaner cleaner = cleaner(e)) { 508 Future future = e.submit(callable); 509 assertSame(TEST_STRING, future.get()); 510 } 511 }}; 512 513 runWithPermissions(r, new RuntimePermission("modifyThread")); 514 } 515 516 /** 517 * A submitted privileged exception action runs to completion 518 */ 519 public void testSubmitPrivilegedExceptionAction() throws Exception { 520 final Callable callable = 521 Executors.callable(new PrivilegedExceptionAction() { 522 public Object run() { return TEST_STRING; }}); 523 Runnable r = new CheckedRunnable() { 524 public void realRun() throws Exception { 525 ExecutorService e = new ForkJoinPool(1); 526 try (PoolCleaner cleaner = cleaner(e)) { 527 Future future = e.submit(callable); 528 assertSame(TEST_STRING, future.get()); 529 } 530 }}; 531 532 runWithPermissions(r, new RuntimePermission("modifyThread")); 533 } 534 535 /** 536 * A submitted failed privileged exception action reports exception 537 */ 538 public void testSubmitFailedPrivilegedExceptionAction() throws Exception { 539 final Callable callable = 540 Executors.callable(new PrivilegedExceptionAction() { 541 public Object run() { throw new IndexOutOfBoundsException(); }}); 542 Runnable r = new CheckedRunnable() { 543 public void realRun() throws Exception { 544 ExecutorService e = new ForkJoinPool(1); 545 try (PoolCleaner cleaner = cleaner(e)) { 546 Future future = e.submit(callable); 547 try { 548 future.get(); 549 shouldThrow(); 550 } catch (ExecutionException success) { 551 assertTrue(success.getCause() instanceof IndexOutOfBoundsException); 552 } 553 } 554 }}; 555 556 runWithPermissions(r, new RuntimePermission("modifyThread")); 557 } 558 559 /** 560 * execute(null runnable) throws NullPointerException 561 */ 562 public void testExecuteNullRunnable() { 563 ExecutorService e = new ForkJoinPool(1); 564 try (PoolCleaner cleaner = cleaner(e)) { 565 try { 566 Future<?> unused = e.submit((Runnable) null); 567 shouldThrow(); 568 } catch (NullPointerException success) {} 569 } 570 } 571 572 /** 573 * submit(null callable) throws NullPointerException 574 */ 575 public void testSubmitNullCallable() { 576 ExecutorService e = new ForkJoinPool(1); 577 try (PoolCleaner cleaner = cleaner(e)) { 578 try { 579 Future<String> unused = e.submit((Callable) null); 580 shouldThrow(); 581 } catch (NullPointerException success) {} 582 } 583 } 584 585 /** 586 * submit(callable).get() throws InterruptedException if interrupted 587 */ 588 public void testInterruptedSubmit() throws InterruptedException { 589 final CountDownLatch submitted = new CountDownLatch(1); 590 final CountDownLatch quittingTime = new CountDownLatch(1); 591 final Callable<Void> awaiter = new CheckedCallable<Void>() { 592 public Void realCall() throws InterruptedException { 593 assertTrue(quittingTime.await(2*LONG_DELAY_MS, MILLISECONDS)); 594 return null; 595 }}; 596 final ExecutorService p = new ForkJoinPool(1); 597 try (PoolCleaner cleaner = cleaner(p, quittingTime)) { 598 Thread t = new Thread(new CheckedInterruptedRunnable() { 599 public void realRun() throws Exception { 600 Future<Void> future = p.submit(awaiter); 601 submitted.countDown(); 602 future.get(); 603 }}); 604 t.start(); 605 await(submitted); 606 t.interrupt(); 607 awaitTermination(t); 608 } 609 } 610 611 /** 612 * get of submit(callable) throws ExecutionException if callable 613 * throws exception 614 */ 615 public void testSubmitEE() throws Throwable { 616 ForkJoinPool p = new ForkJoinPool(1); 617 try (PoolCleaner cleaner = cleaner(p)) { 618 try { 619 p.submit(new Callable() { 620 public Object call() { throw new ArithmeticException(); }}) 621 .get(); 622 shouldThrow(); 623 } catch (ExecutionException success) { 624 assertTrue(success.getCause() instanceof ArithmeticException); 625 } 626 } 627 } 628 629 /** 630 * invokeAny(null) throws NullPointerException 631 */ 632 public void testInvokeAny1() throws Throwable { 633 ExecutorService e = new ForkJoinPool(1); 634 try (PoolCleaner cleaner = cleaner(e)) { 635 try { 636 e.invokeAny(null); 637 shouldThrow(); 638 } catch (NullPointerException success) {} 639 } 640 } 641 642 /** 643 * invokeAny(empty collection) throws IllegalArgumentException 644 */ 645 public void testInvokeAny2() throws Throwable { 646 ExecutorService e = new ForkJoinPool(1); 647 try (PoolCleaner cleaner = cleaner(e)) { 648 try { 649 e.invokeAny(new ArrayList<Callable<String>>()); 650 shouldThrow(); 651 } catch (IllegalArgumentException success) {} 652 } 653 } 654 655 /** 656 * invokeAny(c) throws NullPointerException if c has a single null element 657 */ 658 public void testInvokeAny3() throws Throwable { 659 ExecutorService e = new ForkJoinPool(1); 660 try (PoolCleaner cleaner = cleaner(e)) { 661 List<Callable<String>> l = new ArrayList<>(); 662 l.add(null); 663 try { 664 e.invokeAny(l); 665 shouldThrow(); 666 } catch (NullPointerException success) {} 667 } 668 } 669 670 /** 671 * invokeAny(c) throws NullPointerException if c has null elements 672 */ 673 public void testInvokeAny4() throws Throwable { 674 CountDownLatch latch = new CountDownLatch(1); 675 ExecutorService e = new ForkJoinPool(1); 676 try (PoolCleaner cleaner = cleaner(e)) { 677 List<Callable<String>> l = new ArrayList<>(); 678 l.add(latchAwaitingStringTask(latch)); 679 l.add(null); 680 try { 681 e.invokeAny(l); 682 shouldThrow(); 683 } catch (NullPointerException success) {} 684 latch.countDown(); 685 } 686 } 687 688 /** 689 * invokeAny(c) throws ExecutionException if no task in c completes 690 */ 691 public void testInvokeAny5() throws Throwable { 692 ExecutorService e = new ForkJoinPool(1); 693 try (PoolCleaner cleaner = cleaner(e)) { 694 List<Callable<String>> l = new ArrayList<>(); 695 l.add(new NPETask()); 696 try { 697 e.invokeAny(l); 698 shouldThrow(); 699 } catch (ExecutionException success) { 700 assertTrue(success.getCause() instanceof NullPointerException); 701 } 702 } 703 } 704 705 /** 706 * invokeAny(c) returns result of some task in c if at least one completes 707 */ 708 public void testInvokeAny6() throws Throwable { 709 ExecutorService e = new ForkJoinPool(1); 710 try (PoolCleaner cleaner = cleaner(e)) { 711 List<Callable<String>> l = new ArrayList<>(); 712 l.add(new StringTask()); 713 l.add(new StringTask()); 714 String result = e.invokeAny(l); 715 assertSame(TEST_STRING, result); 716 } 717 } 718 719 /** 720 * invokeAll(null) throws NullPointerException 721 */ 722 public void testInvokeAll1() throws Throwable { 723 ExecutorService e = new ForkJoinPool(1); 724 try (PoolCleaner cleaner = cleaner(e)) { 725 try { 726 e.invokeAll(null); 727 shouldThrow(); 728 } catch (NullPointerException success) {} 729 } 730 } 731 732 /** 733 * invokeAll(empty collection) returns empty list 734 */ 735 public void testInvokeAll2() throws InterruptedException { 736 ExecutorService e = new ForkJoinPool(1); 737 final Collection<Callable<String>> emptyCollection 738 = Collections.emptyList(); 739 try (PoolCleaner cleaner = cleaner(e)) { 740 List<Future<String>> r = e.invokeAll(emptyCollection); 741 assertTrue(r.isEmpty()); 742 } 743 } 744 745 /** 746 * invokeAll(c) throws NullPointerException if c has null elements 747 */ 748 public void testInvokeAll3() throws InterruptedException { 749 ExecutorService e = new ForkJoinPool(1); 750 try (PoolCleaner cleaner = cleaner(e)) { 751 List<Callable<String>> l = new ArrayList<>(); 752 l.add(new StringTask()); 753 l.add(null); 754 try { 755 e.invokeAll(l); 756 shouldThrow(); 757 } catch (NullPointerException success) {} 758 } 759 } 760 761 /** 762 * get of returned element of invokeAll(c) throws 763 * ExecutionException on failed task 764 */ 765 public void testInvokeAll4() throws Throwable { 766 ExecutorService e = new ForkJoinPool(1); 767 try (PoolCleaner cleaner = cleaner(e)) { 768 List<Callable<String>> l = new ArrayList<>(); 769 l.add(new NPETask()); 770 List<Future<String>> futures = e.invokeAll(l); 771 assertEquals(1, futures.size()); 772 try { 773 futures.get(0).get(); 774 shouldThrow(); 775 } catch (ExecutionException success) { 776 assertTrue(success.getCause() instanceof NullPointerException); 777 } 778 } 779 } 780 781 /** 782 * invokeAll(c) returns results of all completed tasks in c 783 */ 784 public void testInvokeAll5() throws Throwable { 785 ExecutorService e = new ForkJoinPool(1); 786 try (PoolCleaner cleaner = cleaner(e)) { 787 List<Callable<String>> l = new ArrayList<>(); 788 l.add(new StringTask()); 789 l.add(new StringTask()); 790 List<Future<String>> futures = e.invokeAll(l); 791 assertEquals(2, futures.size()); 792 for (Future<String> future : futures) 793 assertSame(TEST_STRING, future.get()); 794 } 795 } 796 797 /** 798 * timed invokeAny(null) throws NullPointerException 799 */ 800 public void testTimedInvokeAny1() throws Throwable { 801 ExecutorService e = new ForkJoinPool(1); 802 try (PoolCleaner cleaner = cleaner(e)) { 803 try { 804 e.invokeAny(null, randomTimeout(), randomTimeUnit()); 805 shouldThrow(); 806 } catch (NullPointerException success) {} 807 } 808 } 809 810 /** 811 * timed invokeAny(null time unit) throws NullPointerException 812 */ 813 public void testTimedInvokeAnyNullTimeUnit() throws Throwable { 814 ExecutorService e = new ForkJoinPool(1); 815 try (PoolCleaner cleaner = cleaner(e)) { 816 List<Callable<String>> l = new ArrayList<>(); 817 l.add(new StringTask()); 818 try { 819 e.invokeAny(l, randomTimeout(), null); 820 shouldThrow(); 821 } catch (NullPointerException success) {} 822 } 823 } 824 825 /** 826 * timed invokeAny(empty collection) throws IllegalArgumentException 827 */ 828 public void testTimedInvokeAny2() throws Throwable { 829 ExecutorService e = new ForkJoinPool(1); 830 try (PoolCleaner cleaner = cleaner(e)) { 831 try { 832 e.invokeAny(new ArrayList<Callable<String>>(), 833 randomTimeout(), randomTimeUnit()); 834 shouldThrow(); 835 } catch (IllegalArgumentException success) {} 836 } 837 } 838 839 /** 840 * timed invokeAny(c) throws NullPointerException if c has null elements 841 */ 842 public void testTimedInvokeAny3() throws Throwable { 843 CountDownLatch latch = new CountDownLatch(1); 844 ExecutorService e = new ForkJoinPool(1); 845 try (PoolCleaner cleaner = cleaner(e)) { 846 List<Callable<String>> l = new ArrayList<>(); 847 l.add(latchAwaitingStringTask(latch)); 848 l.add(null); 849 try { 850 e.invokeAny(l, randomTimeout(), randomTimeUnit()); 851 shouldThrow(); 852 } catch (NullPointerException success) {} 853 latch.countDown(); 854 } 855 } 856 857 /** 858 * timed invokeAny(c) throws ExecutionException if no task completes 859 */ 860 public void testTimedInvokeAny4() throws Throwable { 861 ExecutorService e = new ForkJoinPool(1); 862 try (PoolCleaner cleaner = cleaner(e)) { 863 long startTime = System.nanoTime(); 864 List<Callable<String>> l = new ArrayList<>(); 865 l.add(new NPETask()); 866 try { 867 e.invokeAny(l, LONG_DELAY_MS, MILLISECONDS); 868 shouldThrow(); 869 } catch (ExecutionException success) { 870 assertTrue(success.getCause() instanceof NullPointerException); 871 } 872 assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS); 873 } 874 } 875 876 /** 877 * timed invokeAny(c) returns result of some task in c 878 */ 879 public void testTimedInvokeAny5() throws Throwable { 880 ExecutorService e = new ForkJoinPool(1); 881 try (PoolCleaner cleaner = cleaner(e)) { 882 long startTime = System.nanoTime(); 883 List<Callable<String>> l = new ArrayList<>(); 884 l.add(new StringTask()); 885 l.add(new StringTask()); 886 String result = e.invokeAny(l, LONG_DELAY_MS, MILLISECONDS); 887 assertSame(TEST_STRING, result); 888 assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS); 889 } 890 } 891 892 /** 893 * timed invokeAll(null) throws NullPointerException 894 */ 895 public void testTimedInvokeAll1() throws Throwable { 896 ExecutorService e = new ForkJoinPool(1); 897 try (PoolCleaner cleaner = cleaner(e)) { 898 try { 899 e.invokeAll(null, randomTimeout(), randomTimeUnit()); 900 shouldThrow(); 901 } catch (NullPointerException success) {} 902 } 903 } 904 905 /** 906 * timed invokeAll(null time unit) throws NullPointerException 907 */ 908 public void testTimedInvokeAllNullTimeUnit() throws Throwable { 909 ExecutorService e = new ForkJoinPool(1); 910 try (PoolCleaner cleaner = cleaner(e)) { 911 List<Callable<String>> l = new ArrayList<>(); 912 l.add(new StringTask()); 913 try { 914 e.invokeAll(l, randomTimeout(), null); 915 shouldThrow(); 916 } catch (NullPointerException success) {} 917 } 918 } 919 920 /** 921 * timed invokeAll(empty collection) returns empty list 922 */ 923 public void testTimedInvokeAll2() throws InterruptedException { 924 ExecutorService e = new ForkJoinPool(1); 925 final Collection<Callable<String>> emptyCollection 926 = Collections.emptyList(); 927 try (PoolCleaner cleaner = cleaner(e)) { 928 List<Future<String>> r 929 = e.invokeAll(emptyCollection, 930 randomTimeout(), randomTimeUnit()); 931 assertTrue(r.isEmpty()); 932 } 933 } 934 935 /** 936 * timed invokeAll(c) throws NullPointerException if c has null elements 937 */ 938 public void testTimedInvokeAll3() throws InterruptedException { 939 ExecutorService e = new ForkJoinPool(1); 940 try (PoolCleaner cleaner = cleaner(e)) { 941 List<Callable<String>> l = new ArrayList<>(); 942 l.add(new StringTask()); 943 l.add(null); 944 try { 945 e.invokeAll(l, randomTimeout(), randomTimeUnit()); 946 shouldThrow(); 947 } catch (NullPointerException success) {} 948 } 949 } 950 951 /** 952 * get of returned element of invokeAll(c) throws exception on failed task 953 */ 954 public void testTimedInvokeAll4() throws Throwable { 955 ExecutorService e = new ForkJoinPool(1); 956 try (PoolCleaner cleaner = cleaner(e)) { 957 List<Callable<String>> l = new ArrayList<>(); 958 l.add(new NPETask()); 959 List<Future<String>> futures 960 = e.invokeAll(l, LONG_DELAY_MS, MILLISECONDS); 961 assertEquals(1, futures.size()); 962 try { 963 futures.get(0).get(); 964 shouldThrow(); 965 } catch (ExecutionException success) { 966 assertTrue(success.getCause() instanceof NullPointerException); 967 } 968 } 969 } 970 971 /** 972 * timed invokeAll(c) returns results of all completed tasks in c 973 */ 974 public void testTimedInvokeAll5() throws Throwable { 975 ForkJoinPool e = new ForkJoinPool(1); 976 try (PoolCleaner cleaner = cleaner(e)) { 977 List<Callable<String>> l = new ArrayList<>(); 978 l.add(new StringTask()); 979 l.add(new StringTask()); 980 List<Future<String>> futures 981 = e.invokeAll(l, LONG_DELAY_MS, MILLISECONDS); 982 assertEquals(2, futures.size()); 983 for (Future<String> future : futures) 984 assertSame(TEST_STRING, future.get()); 985 } 986 } 987 988 }