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. Oracle designates this 7 * particular file as subject to the "Classpath" exception as provided 8 * by Oracle in the LICENSE file that accompanied this code. 9 * 10 * This code is distributed in the hope that it will be useful, but WITHOUT 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 * version 2 for more details (a copy is included in the LICENSE file that 14 * accompanied this code). 15 * 16 * You should have received a copy of the GNU General Public License version 17 * 2 along with this work; if not, write to the Free Software Foundation, 18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 * 20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21 * or visit www.oracle.com if you need additional information or have any 22 * questions. 23 */ 24 25 /* 26 * This file is available under and governed by the GNU General Public 27 * License version 2 only, as published by the Free Software Foundation. 28 * However, the following notice accompanied the original version of this 29 * file: 30 * 31 * Written by Doug Lea with assistance from members of JCP JSR-166 32 * Expert Group and released to the public domain, as explained at 33 * http://creativecommons.org/publicdomain/zero/1.0/ 34 */ 35 36 package java.util.concurrent; 37 38 import static java.lang.ref.Reference.reachabilityFence; 39 import dalvik.annotation.optimization.ReachabilitySensitive; 40 import java.security.AccessControlContext; 41 import java.security.AccessControlException; 42 import java.security.AccessController; 43 import java.security.PrivilegedAction; 44 import java.security.PrivilegedActionException; 45 import java.security.PrivilegedExceptionAction; 46 import java.util.Collection; 47 import java.util.List; 48 import java.util.concurrent.atomic.AtomicInteger; 49 import sun.security.util.SecurityConstants; 50 51 // BEGIN android-note 52 // removed security manager docs 53 // END android-note 54 55 /** 56 * Factory and utility methods for {@link Executor}, {@link 57 * ExecutorService}, {@link ScheduledExecutorService}, {@link 58 * ThreadFactory}, and {@link Callable} classes defined in this 59 * package. This class supports the following kinds of methods: 60 * 61 * <ul> 62 * <li>Methods that create and return an {@link ExecutorService} 63 * set up with commonly useful configuration settings. 64 * <li>Methods that create and return a {@link ScheduledExecutorService} 65 * set up with commonly useful configuration settings. 66 * <li>Methods that create and return a "wrapped" ExecutorService, that 67 * disables reconfiguration by making implementation-specific methods 68 * inaccessible. 69 * <li>Methods that create and return a {@link ThreadFactory} 70 * that sets newly created threads to a known state. 71 * <li>Methods that create and return a {@link Callable} 72 * out of other closure-like forms, so they can be used 73 * in execution methods requiring {@code Callable}. 74 * </ul> 75 * 76 * @since 1.5 77 * @author Doug Lea 78 */ 79 public class Executors { 80 81 /** 82 * Creates a thread pool that reuses a fixed number of threads 83 * operating off a shared unbounded queue. At any point, at most 84 * {@code nThreads} threads will be active processing tasks. 85 * If additional tasks are submitted when all threads are active, 86 * they will wait in the queue until a thread is available. 87 * If any thread terminates due to a failure during execution 88 * prior to shutdown, a new one will take its place if needed to 89 * execute subsequent tasks. The threads in the pool will exist 90 * until it is explicitly {@link ExecutorService#shutdown shutdown}. 91 * 92 * @param nThreads the number of threads in the pool 93 * @return the newly created thread pool 94 * @throws IllegalArgumentException if {@code nThreads <= 0} 95 */ newFixedThreadPool(int nThreads)96 public static ExecutorService newFixedThreadPool(int nThreads) { 97 return new ThreadPoolExecutor(nThreads, nThreads, 98 0L, TimeUnit.MILLISECONDS, 99 new LinkedBlockingQueue<Runnable>()); 100 } 101 102 /** 103 * Creates a thread pool that maintains enough threads to support 104 * the given parallelism level, and may use multiple queues to 105 * reduce contention. The parallelism level corresponds to the 106 * maximum number of threads actively engaged in, or available to 107 * engage in, task processing. The actual number of threads may 108 * grow and shrink dynamically. A work-stealing pool makes no 109 * guarantees about the order in which submitted tasks are 110 * executed. 111 * 112 * @param parallelism the targeted parallelism level 113 * @return the newly created thread pool 114 * @throws IllegalArgumentException if {@code parallelism <= 0} 115 * @since 1.8 116 */ newWorkStealingPool(int parallelism)117 public static ExecutorService newWorkStealingPool(int parallelism) { 118 return new ForkJoinPool 119 (parallelism, 120 ForkJoinPool.defaultForkJoinWorkerThreadFactory, 121 null, true); 122 } 123 124 /** 125 * Creates a work-stealing thread pool using the number of 126 * {@linkplain Runtime#availableProcessors available processors} 127 * as its target parallelism level. 128 * 129 * @return the newly created thread pool 130 * @see #newWorkStealingPool(int) 131 * @since 1.8 132 */ newWorkStealingPool()133 public static ExecutorService newWorkStealingPool() { 134 return new ForkJoinPool 135 (Runtime.getRuntime().availableProcessors(), 136 ForkJoinPool.defaultForkJoinWorkerThreadFactory, 137 null, true); 138 } 139 140 /** 141 * Creates a thread pool that reuses a fixed number of threads 142 * operating off a shared unbounded queue, using the provided 143 * ThreadFactory to create new threads when needed. At any point, 144 * at most {@code nThreads} threads will be active processing 145 * tasks. If additional tasks are submitted when all threads are 146 * active, they will wait in the queue until a thread is 147 * available. If any thread terminates due to a failure during 148 * execution prior to shutdown, a new one will take its place if 149 * needed to execute subsequent tasks. The threads in the pool will 150 * exist until it is explicitly {@link ExecutorService#shutdown 151 * shutdown}. 152 * 153 * @param nThreads the number of threads in the pool 154 * @param threadFactory the factory to use when creating new threads 155 * @return the newly created thread pool 156 * @throws NullPointerException if threadFactory is null 157 * @throws IllegalArgumentException if {@code nThreads <= 0} 158 */ newFixedThreadPool(int nThreads, ThreadFactory threadFactory)159 public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) { 160 return new ThreadPoolExecutor(nThreads, nThreads, 161 0L, TimeUnit.MILLISECONDS, 162 new LinkedBlockingQueue<Runnable>(), 163 threadFactory); 164 } 165 166 /** 167 * Creates an Executor that uses a single worker thread operating 168 * off an unbounded queue. (Note however that if this single 169 * thread terminates due to a failure during execution prior to 170 * shutdown, a new one will take its place if needed to execute 171 * subsequent tasks.) Tasks are guaranteed to execute 172 * sequentially, and no more than one task will be active at any 173 * given time. Unlike the otherwise equivalent 174 * {@code newFixedThreadPool(1)} the returned executor is 175 * guaranteed not to be reconfigurable to use additional threads. 176 * 177 * @return the newly created single-threaded Executor 178 */ newSingleThreadExecutor()179 public static ExecutorService newSingleThreadExecutor() { 180 return new FinalizableDelegatedExecutorService 181 (new ThreadPoolExecutor(1, 1, 182 0L, TimeUnit.MILLISECONDS, 183 new LinkedBlockingQueue<Runnable>())); 184 } 185 186 /** 187 * Creates an Executor that uses a single worker thread operating 188 * off an unbounded queue, and uses the provided ThreadFactory to 189 * create a new thread when needed. Unlike the otherwise 190 * equivalent {@code newFixedThreadPool(1, threadFactory)} the 191 * returned executor is guaranteed not to be reconfigurable to use 192 * additional threads. 193 * 194 * @param threadFactory the factory to use when creating new threads 195 * @return the newly created single-threaded Executor 196 * @throws NullPointerException if threadFactory is null 197 */ newSingleThreadExecutor(ThreadFactory threadFactory)198 public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) { 199 return new FinalizableDelegatedExecutorService 200 (new ThreadPoolExecutor(1, 1, 201 0L, TimeUnit.MILLISECONDS, 202 new LinkedBlockingQueue<Runnable>(), 203 threadFactory)); 204 } 205 206 /** 207 * Creates a thread pool that creates new threads as needed, but 208 * will reuse previously constructed threads when they are 209 * available. These pools will typically improve the performance 210 * of programs that execute many short-lived asynchronous tasks. 211 * Calls to {@code execute} will reuse previously constructed 212 * threads if available. If no existing thread is available, a new 213 * thread will be created and added to the pool. Threads that have 214 * not been used for sixty seconds are terminated and removed from 215 * the cache. Thus, a pool that remains idle for long enough will 216 * not consume any resources. Note that pools with similar 217 * properties but different details (for example, timeout parameters) 218 * may be created using {@link ThreadPoolExecutor} constructors. 219 * 220 * @return the newly created thread pool 221 */ newCachedThreadPool()222 public static ExecutorService newCachedThreadPool() { 223 return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 224 60L, TimeUnit.SECONDS, 225 new SynchronousQueue<Runnable>()); 226 } 227 228 /** 229 * Creates a thread pool that creates new threads as needed, but 230 * will reuse previously constructed threads when they are 231 * available, and uses the provided 232 * ThreadFactory to create new threads when needed. 233 * 234 * @param threadFactory the factory to use when creating new threads 235 * @return the newly created thread pool 236 * @throws NullPointerException if threadFactory is null 237 */ newCachedThreadPool(ThreadFactory threadFactory)238 public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) { 239 return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 240 60L, TimeUnit.SECONDS, 241 new SynchronousQueue<Runnable>(), 242 threadFactory); 243 } 244 245 /** 246 * Creates a single-threaded executor that can schedule commands 247 * to run after a given delay, or to execute periodically. 248 * (Note however that if this single 249 * thread terminates due to a failure during execution prior to 250 * shutdown, a new one will take its place if needed to execute 251 * subsequent tasks.) Tasks are guaranteed to execute 252 * sequentially, and no more than one task will be active at any 253 * given time. Unlike the otherwise equivalent 254 * {@code newScheduledThreadPool(1)} the returned executor is 255 * guaranteed not to be reconfigurable to use additional threads. 256 * 257 * @return the newly created scheduled executor 258 */ newSingleThreadScheduledExecutor()259 public static ScheduledExecutorService newSingleThreadScheduledExecutor() { 260 return new DelegatedScheduledExecutorService 261 (new ScheduledThreadPoolExecutor(1)); 262 } 263 264 /** 265 * Creates a single-threaded executor that can schedule commands 266 * to run after a given delay, or to execute periodically. (Note 267 * however that if this single thread terminates due to a failure 268 * during execution prior to shutdown, a new one will take its 269 * place if needed to execute subsequent tasks.) Tasks are 270 * guaranteed to execute sequentially, and no more than one task 271 * will be active at any given time. Unlike the otherwise 272 * equivalent {@code newScheduledThreadPool(1, threadFactory)} 273 * the returned executor is guaranteed not to be reconfigurable to 274 * use additional threads. 275 * 276 * @param threadFactory the factory to use when creating new threads 277 * @return the newly created scheduled executor 278 * @throws NullPointerException if threadFactory is null 279 */ newSingleThreadScheduledExecutor(ThreadFactory threadFactory)280 public static ScheduledExecutorService newSingleThreadScheduledExecutor(ThreadFactory threadFactory) { 281 return new DelegatedScheduledExecutorService 282 (new ScheduledThreadPoolExecutor(1, threadFactory)); 283 } 284 285 /** 286 * Creates a thread pool that can schedule commands to run after a 287 * given delay, or to execute periodically. 288 * @param corePoolSize the number of threads to keep in the pool, 289 * even if they are idle 290 * @return the newly created scheduled thread pool 291 * @throws IllegalArgumentException if {@code corePoolSize < 0} 292 */ newScheduledThreadPool(int corePoolSize)293 public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) { 294 return new ScheduledThreadPoolExecutor(corePoolSize); 295 } 296 297 /** 298 * Creates a thread pool that can schedule commands to run after a 299 * given delay, or to execute periodically. 300 * @param corePoolSize the number of threads to keep in the pool, 301 * even if they are idle 302 * @param threadFactory the factory to use when the executor 303 * creates a new thread 304 * @return the newly created scheduled thread pool 305 * @throws IllegalArgumentException if {@code corePoolSize < 0} 306 * @throws NullPointerException if threadFactory is null 307 */ newScheduledThreadPool( int corePoolSize, ThreadFactory threadFactory)308 public static ScheduledExecutorService newScheduledThreadPool( 309 int corePoolSize, ThreadFactory threadFactory) { 310 return new ScheduledThreadPoolExecutor(corePoolSize, threadFactory); 311 } 312 313 /** 314 * Returns an object that delegates all defined {@link 315 * ExecutorService} methods to the given executor, but not any 316 * other methods that might otherwise be accessible using 317 * casts. This provides a way to safely "freeze" configuration and 318 * disallow tuning of a given concrete implementation. 319 * @param executor the underlying implementation 320 * @return an {@code ExecutorService} instance 321 * @throws NullPointerException if executor null 322 */ unconfigurableExecutorService(ExecutorService executor)323 public static ExecutorService unconfigurableExecutorService(ExecutorService executor) { 324 if (executor == null) 325 throw new NullPointerException(); 326 return new DelegatedExecutorService(executor); 327 } 328 329 /** 330 * Returns an object that delegates all defined {@link 331 * ScheduledExecutorService} methods to the given executor, but 332 * not any other methods that might otherwise be accessible using 333 * casts. This provides a way to safely "freeze" configuration and 334 * disallow tuning of a given concrete implementation. 335 * @param executor the underlying implementation 336 * @return a {@code ScheduledExecutorService} instance 337 * @throws NullPointerException if executor null 338 */ unconfigurableScheduledExecutorService(ScheduledExecutorService executor)339 public static ScheduledExecutorService unconfigurableScheduledExecutorService(ScheduledExecutorService executor) { 340 if (executor == null) 341 throw new NullPointerException(); 342 return new DelegatedScheduledExecutorService(executor); 343 } 344 345 // Android-changed: Removed references to SecurityManager from javadoc. 346 /** 347 * Returns a default thread factory used to create new threads. 348 * This factory creates all new threads used by an Executor in the 349 * same {@link ThreadGroup}. Each new 350 * thread is created as a non-daemon thread with priority set to 351 * the smaller of {@code Thread.NORM_PRIORITY} and the maximum 352 * priority permitted in the thread group. New threads have names 353 * accessible via {@link Thread#getName} of 354 * <em>pool-N-thread-M</em>, where <em>N</em> is the sequence 355 * number of this factory, and <em>M</em> is the sequence number 356 * of the thread created by this factory. 357 * @return a thread factory 358 */ defaultThreadFactory()359 public static ThreadFactory defaultThreadFactory() { 360 return new DefaultThreadFactory(); 361 } 362 363 // Android-changed: Dropped documentation for legacy security code. 364 /** 365 * Legacy security code; do not use. 366 */ privilegedThreadFactory()367 public static ThreadFactory privilegedThreadFactory() { 368 return new PrivilegedThreadFactory(); 369 } 370 371 /** 372 * Returns a {@link Callable} object that, when 373 * called, runs the given task and returns the given result. This 374 * can be useful when applying methods requiring a 375 * {@code Callable} to an otherwise resultless action. 376 * @param task the task to run 377 * @param result the result to return 378 * @param <T> the type of the result 379 * @return a callable object 380 * @throws NullPointerException if task null 381 */ callable(Runnable task, T result)382 public static <T> Callable<T> callable(Runnable task, T result) { 383 if (task == null) 384 throw new NullPointerException(); 385 return new RunnableAdapter<T>(task, result); 386 } 387 388 /** 389 * Returns a {@link Callable} object that, when 390 * called, runs the given task and returns {@code null}. 391 * @param task the task to run 392 * @return a callable object 393 * @throws NullPointerException if task null 394 */ callable(Runnable task)395 public static Callable<Object> callable(Runnable task) { 396 if (task == null) 397 throw new NullPointerException(); 398 return new RunnableAdapter<Object>(task, null); 399 } 400 401 /** 402 * Returns a {@link Callable} object that, when 403 * called, runs the given privileged action and returns its result. 404 * @param action the privileged action to run 405 * @return a callable object 406 * @throws NullPointerException if action null 407 */ callable(final PrivilegedAction<?> action)408 public static Callable<Object> callable(final PrivilegedAction<?> action) { 409 if (action == null) 410 throw new NullPointerException(); 411 return new Callable<Object>() { 412 public Object call() { return action.run(); }}; 413 } 414 415 /** 416 * Returns a {@link Callable} object that, when 417 * called, runs the given privileged exception action and returns 418 * its result. 419 * @param action the privileged exception action to run 420 * @return a callable object 421 * @throws NullPointerException if action null 422 */ 423 public static Callable<Object> callable(final PrivilegedExceptionAction<?> action) { 424 if (action == null) 425 throw new NullPointerException(); 426 return new Callable<Object>() { 427 public Object call() throws Exception { return action.run(); }}; 428 } 429 430 // Android-changed: Dropped documentation for legacy security code. 431 /** 432 * Legacy security code; do not use. 433 */ 434 public static <T> Callable<T> privilegedCallable(Callable<T> callable) { 435 if (callable == null) 436 throw new NullPointerException(); 437 return new PrivilegedCallable<T>(callable); 438 } 439 440 // Android-changed: Dropped documentation for legacy security code. 441 /** 442 * Legacy security code; do not use. 443 */ 444 public static <T> Callable<T> privilegedCallableUsingCurrentClassLoader(Callable<T> callable) { 445 if (callable == null) 446 throw new NullPointerException(); 447 return new PrivilegedCallableUsingCurrentClassLoader<T>(callable); 448 } 449 450 // Non-public classes supporting the public methods 451 452 /** 453 * A callable that runs given task and returns given result. 454 */ 455 private static final class RunnableAdapter<T> implements Callable<T> { 456 private final Runnable task; 457 private final T result; 458 RunnableAdapter(Runnable task, T result) { 459 this.task = task; 460 this.result = result; 461 } 462 public T call() { 463 task.run(); 464 return result; 465 } 466 public String toString() { 467 return super.toString() + "[Wrapped task = " + task + "]"; 468 } 469 } 470 471 /** 472 * A callable that runs under established access control settings. 473 */ 474 private static final class PrivilegedCallable<T> implements Callable<T> { 475 final Callable<T> task; 476 final AccessControlContext acc; 477 478 PrivilegedCallable(Callable<T> task) { 479 this.task = task; 480 this.acc = AccessController.getContext(); 481 } 482 483 public T call() throws Exception { 484 try { 485 return AccessController.doPrivileged( 486 new PrivilegedExceptionAction<T>() { 487 public T run() throws Exception { 488 return task.call(); 489 } 490 }, acc); 491 } catch (PrivilegedActionException e) { 492 throw e.getException(); 493 } 494 } 495 496 public String toString() { 497 return super.toString() + "[Wrapped task = " + task + "]"; 498 } 499 } 500 501 /** 502 * A callable that runs under established access control settings and 503 * current ClassLoader. 504 */ 505 private static final class PrivilegedCallableUsingCurrentClassLoader<T> 506 implements Callable<T> { 507 final Callable<T> task; 508 final AccessControlContext acc; 509 final ClassLoader ccl; 510 511 PrivilegedCallableUsingCurrentClassLoader(Callable<T> task) { 512 // Android-removed: System.getSecurityManager always returns null. 513 /* 514 SecurityManager sm = System.getSecurityManager(); 515 if (sm != null) { 516 // Calls to getContextClassLoader from this class 517 // never trigger a security check, but we check 518 // whether our callers have this permission anyways. 519 sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION); 520 521 // Whether setContextClassLoader turns out to be necessary 522 // or not, we fail fast if permission is not available. 523 sm.checkPermission(new RuntimePermission("setContextClassLoader")); 524 } 525 */ 526 this.task = task; 527 this.acc = AccessController.getContext(); 528 this.ccl = Thread.currentThread().getContextClassLoader(); 529 } 530 531 public T call() throws Exception { 532 try { 533 return AccessController.doPrivileged( 534 new PrivilegedExceptionAction<T>() { 535 public T run() throws Exception { 536 Thread t = Thread.currentThread(); 537 ClassLoader cl = t.getContextClassLoader(); 538 if (ccl == cl) { 539 return task.call(); 540 } else { 541 t.setContextClassLoader(ccl); 542 try { 543 return task.call(); 544 } finally { 545 t.setContextClassLoader(cl); 546 } 547 } 548 } 549 }, acc); 550 } catch (PrivilegedActionException e) { 551 throw e.getException(); 552 } 553 } 554 555 public String toString() { 556 return super.toString() + "[Wrapped task = " + task + "]"; 557 } 558 } 559 560 /** 561 * The default thread factory. 562 */ 563 private static class DefaultThreadFactory implements ThreadFactory { 564 private static final AtomicInteger poolNumber = new AtomicInteger(1); 565 private final ThreadGroup group; 566 private final AtomicInteger threadNumber = new AtomicInteger(1); 567 private final String namePrefix; 568 569 DefaultThreadFactory() { 570 SecurityManager s = System.getSecurityManager(); 571 group = (s != null) ? s.getThreadGroup() : 572 Thread.currentThread().getThreadGroup(); 573 namePrefix = "pool-" + 574 poolNumber.getAndIncrement() + 575 "-thread-"; 576 } 577 578 public Thread newThread(Runnable r) { 579 Thread t = new Thread(group, r, 580 namePrefix + threadNumber.getAndIncrement(), 581 0); 582 if (t.isDaemon()) 583 t.setDaemon(false); 584 if (t.getPriority() != Thread.NORM_PRIORITY) 585 t.setPriority(Thread.NORM_PRIORITY); 586 return t; 587 } 588 } 589 590 /** 591 * Thread factory capturing access control context and class loader. 592 */ 593 private static class PrivilegedThreadFactory extends DefaultThreadFactory { 594 final AccessControlContext acc; 595 final ClassLoader ccl; 596 597 PrivilegedThreadFactory() { 598 super(); 599 // Android-removed: System.getSecurityManager always returns null. 600 /* 601 SecurityManager sm = System.getSecurityManager(); 602 if (sm != null) { 603 // Calls to getContextClassLoader from this class 604 // never trigger a security check, but we check 605 // whether our callers have this permission anyways. 606 sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION); 607 608 // Fail fast 609 sm.checkPermission(new RuntimePermission("setContextClassLoader")); 610 } 611 */ 612 this.acc = AccessController.getContext(); 613 this.ccl = Thread.currentThread().getContextClassLoader(); 614 } 615 616 public Thread newThread(final Runnable r) { 617 return super.newThread(new Runnable() { 618 public void run() { 619 AccessController.doPrivileged(new PrivilegedAction<>() { 620 public Void run() { 621 Thread.currentThread().setContextClassLoader(ccl); 622 r.run(); 623 return null; 624 } 625 }, acc); 626 } 627 }); 628 } 629 } 630 631 /** 632 * A wrapper class that exposes only the ExecutorService methods 633 * of an ExecutorService implementation. 634 */ 635 private static class DelegatedExecutorService 636 implements ExecutorService { 637 // Android-added: @ReachabilitySensitive 638 // Needed for FinalizableDelegatedExecutorService below. 639 @ReachabilitySensitive 640 private final ExecutorService e; 641 DelegatedExecutorService(ExecutorService executor) { e = executor; } 642 public void execute(Runnable command) { 643 try { 644 e.execute(command); 645 } finally { reachabilityFence(this); } 646 } 647 public void shutdown() { e.shutdown(); } 648 public List<Runnable> shutdownNow() { 649 try { 650 return e.shutdownNow(); 651 } finally { reachabilityFence(this); } 652 } 653 public boolean isShutdown() { 654 try { 655 return e.isShutdown(); 656 } finally { reachabilityFence(this); } 657 } 658 public boolean isTerminated() { 659 try { 660 return e.isTerminated(); 661 } finally { reachabilityFence(this); } 662 } 663 public boolean awaitTermination(long timeout, TimeUnit unit) 664 throws InterruptedException { 665 try { 666 return e.awaitTermination(timeout, unit); 667 } finally { reachabilityFence(this); } 668 } 669 public Future<?> submit(Runnable task) { 670 try { 671 return e.submit(task); 672 } finally { reachabilityFence(this); } 673 } 674 public <T> Future<T> submit(Callable<T> task) { 675 try { 676 return e.submit(task); 677 } finally { reachabilityFence(this); } 678 } 679 public <T> Future<T> submit(Runnable task, T result) { 680 try { 681 return e.submit(task, result); 682 } finally { reachabilityFence(this); } 683 } 684 public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) 685 throws InterruptedException { 686 try { 687 return e.invokeAll(tasks); 688 } finally { reachabilityFence(this); } 689 } 690 public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks, 691 long timeout, TimeUnit unit) 692 throws InterruptedException { 693 try { 694 return e.invokeAll(tasks, timeout, unit); 695 } finally { reachabilityFence(this); } 696 } 697 public <T> T invokeAny(Collection<? extends Callable<T>> tasks) 698 throws InterruptedException, ExecutionException { 699 try { 700 return e.invokeAny(tasks); 701 } finally { reachabilityFence(this); } 702 } 703 public <T> T invokeAny(Collection<? extends Callable<T>> tasks, 704 long timeout, TimeUnit unit) 705 throws InterruptedException, ExecutionException, TimeoutException { 706 try { 707 return e.invokeAny(tasks, timeout, unit); 708 } finally { reachabilityFence(this); } 709 } 710 } 711 712 private static class FinalizableDelegatedExecutorService 713 extends DelegatedExecutorService { 714 FinalizableDelegatedExecutorService(ExecutorService executor) { 715 super(executor); 716 } 717 @SuppressWarnings("deprecation") 718 protected void finalize() { 719 super.shutdown(); 720 } 721 } 722 723 /** 724 * A wrapper class that exposes only the ScheduledExecutorService 725 * methods of a ScheduledExecutorService implementation. 726 */ 727 private static class DelegatedScheduledExecutorService 728 extends DelegatedExecutorService 729 implements ScheduledExecutorService { 730 private final ScheduledExecutorService e; 731 DelegatedScheduledExecutorService(ScheduledExecutorService executor) { 732 super(executor); 733 e = executor; 734 } 735 public ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit) { 736 return e.schedule(command, delay, unit); 737 } 738 public <V> ScheduledFuture<V> schedule(Callable<V> callable, long delay, TimeUnit unit) { 739 return e.schedule(callable, delay, unit); 740 } 741 public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit) { 742 return e.scheduleAtFixedRate(command, initialDelay, period, unit); 743 } 744 public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit) { 745 return e.scheduleWithFixedDelay(command, initialDelay, delay, unit); 746 } 747 } 748 749 /** Cannot instantiate. */ 750 private Executors() {} 751 } 752