src/java.base/share/classes/java/util/concurrent/Executors.java
changeset 48843 21efc1774302
parent 47306 90b7465b9ac7
equal deleted inserted replaced
48842:a5a2e4770524 48843:21efc1774302
    33  * http://creativecommons.org/publicdomain/zero/1.0/
    33  * http://creativecommons.org/publicdomain/zero/1.0/
    34  */
    34  */
    35 
    35 
    36 package java.util.concurrent;
    36 package java.util.concurrent;
    37 
    37 
       
    38 import static java.lang.ref.Reference.reachabilityFence;
    38 import java.security.AccessControlContext;
    39 import java.security.AccessControlContext;
    39 import java.security.AccessControlException;
    40 import java.security.AccessControlException;
    40 import java.security.AccessController;
    41 import java.security.AccessController;
    41 import java.security.PrivilegedAction;
    42 import java.security.PrivilegedAction;
    42 import java.security.PrivilegedActionException;
    43 import java.security.PrivilegedActionException;
   183      * create a new thread when needed. Unlike the otherwise
   184      * create a new thread when needed. Unlike the otherwise
   184      * equivalent {@code newFixedThreadPool(1, threadFactory)} the
   185      * equivalent {@code newFixedThreadPool(1, threadFactory)} the
   185      * returned executor is guaranteed not to be reconfigurable to use
   186      * returned executor is guaranteed not to be reconfigurable to use
   186      * additional threads.
   187      * additional threads.
   187      *
   188      *
   188      * @param threadFactory the factory to use when creating new
   189      * @param threadFactory the factory to use when creating new threads
   189      * threads
       
   190      *
       
   191      * @return the newly created single-threaded Executor
   190      * @return the newly created single-threaded Executor
   192      * @throws NullPointerException if threadFactory is null
   191      * @throws NullPointerException if threadFactory is null
   193      */
   192      */
   194     public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) {
   193     public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) {
   195         return new FinalizableDelegatedExecutorService
   194         return new FinalizableDelegatedExecutorService
   224     /**
   223     /**
   225      * Creates a thread pool that creates new threads as needed, but
   224      * Creates a thread pool that creates new threads as needed, but
   226      * will reuse previously constructed threads when they are
   225      * will reuse previously constructed threads when they are
   227      * available, and uses the provided
   226      * available, and uses the provided
   228      * ThreadFactory to create new threads when needed.
   227      * ThreadFactory to create new threads when needed.
       
   228      *
   229      * @param threadFactory the factory to use when creating new threads
   229      * @param threadFactory the factory to use when creating new threads
   230      * @return the newly created thread pool
   230      * @return the newly created thread pool
   231      * @throws NullPointerException if threadFactory is null
   231      * @throws NullPointerException if threadFactory is null
   232      */
   232      */
   233     public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) {
   233     public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) {
   246      * subsequent tasks.)  Tasks are guaranteed to execute
   246      * subsequent tasks.)  Tasks are guaranteed to execute
   247      * sequentially, and no more than one task will be active at any
   247      * sequentially, and no more than one task will be active at any
   248      * given time. Unlike the otherwise equivalent
   248      * given time. Unlike the otherwise equivalent
   249      * {@code newScheduledThreadPool(1)} the returned executor is
   249      * {@code newScheduledThreadPool(1)} the returned executor is
   250      * guaranteed not to be reconfigurable to use additional threads.
   250      * guaranteed not to be reconfigurable to use additional threads.
       
   251      *
   251      * @return the newly created scheduled executor
   252      * @return the newly created scheduled executor
   252      */
   253      */
   253     public static ScheduledExecutorService newSingleThreadScheduledExecutor() {
   254     public static ScheduledExecutorService newSingleThreadScheduledExecutor() {
   254         return new DelegatedScheduledExecutorService
   255         return new DelegatedScheduledExecutorService
   255             (new ScheduledThreadPoolExecutor(1));
   256             (new ScheduledThreadPoolExecutor(1));
   264      * guaranteed to execute sequentially, and no more than one task
   265      * guaranteed to execute sequentially, and no more than one task
   265      * will be active at any given time. Unlike the otherwise
   266      * will be active at any given time. Unlike the otherwise
   266      * equivalent {@code newScheduledThreadPool(1, threadFactory)}
   267      * equivalent {@code newScheduledThreadPool(1, threadFactory)}
   267      * the returned executor is guaranteed not to be reconfigurable to
   268      * the returned executor is guaranteed not to be reconfigurable to
   268      * use additional threads.
   269      * use additional threads.
   269      * @param threadFactory the factory to use when creating new
   270      *
   270      * threads
   271      * @param threadFactory the factory to use when creating new threads
   271      * @return a newly created scheduled executor
   272      * @return the newly created scheduled executor
   272      * @throws NullPointerException if threadFactory is null
   273      * @throws NullPointerException if threadFactory is null
   273      */
   274      */
   274     public static ScheduledExecutorService newSingleThreadScheduledExecutor(ThreadFactory threadFactory) {
   275     public static ScheduledExecutorService newSingleThreadScheduledExecutor(ThreadFactory threadFactory) {
   275         return new DelegatedScheduledExecutorService
   276         return new DelegatedScheduledExecutorService
   276             (new ScheduledThreadPoolExecutor(1, threadFactory));
   277             (new ScheduledThreadPoolExecutor(1, threadFactory));
   279     /**
   280     /**
   280      * Creates a thread pool that can schedule commands to run after a
   281      * Creates a thread pool that can schedule commands to run after a
   281      * given delay, or to execute periodically.
   282      * given delay, or to execute periodically.
   282      * @param corePoolSize the number of threads to keep in the pool,
   283      * @param corePoolSize the number of threads to keep in the pool,
   283      * even if they are idle
   284      * even if they are idle
   284      * @return a newly created scheduled thread pool
   285      * @return the newly created scheduled thread pool
   285      * @throws IllegalArgumentException if {@code corePoolSize < 0}
   286      * @throws IllegalArgumentException if {@code corePoolSize < 0}
   286      */
   287      */
   287     public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
   288     public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
   288         return new ScheduledThreadPoolExecutor(corePoolSize);
   289         return new ScheduledThreadPoolExecutor(corePoolSize);
   289     }
   290     }
   293      * given delay, or to execute periodically.
   294      * given delay, or to execute periodically.
   294      * @param corePoolSize the number of threads to keep in the pool,
   295      * @param corePoolSize the number of threads to keep in the pool,
   295      * even if they are idle
   296      * even if they are idle
   296      * @param threadFactory the factory to use when the executor
   297      * @param threadFactory the factory to use when the executor
   297      * creates a new thread
   298      * creates a new thread
   298      * @return a newly created scheduled thread pool
   299      * @return the newly created scheduled thread pool
   299      * @throws IllegalArgumentException if {@code corePoolSize < 0}
   300      * @throws IllegalArgumentException if {@code corePoolSize < 0}
   300      * @throws NullPointerException if threadFactory is null
   301      * @throws NullPointerException if threadFactory is null
   301      */
   302      */
   302     public static ScheduledExecutorService newScheduledThreadPool(
   303     public static ScheduledExecutorService newScheduledThreadPool(
   303             int corePoolSize, ThreadFactory threadFactory) {
   304             int corePoolSize, ThreadFactory threadFactory) {
   676     /**
   677     /**
   677      * A wrapper class that exposes only the ExecutorService methods
   678      * A wrapper class that exposes only the ExecutorService methods
   678      * of an ExecutorService implementation.
   679      * of an ExecutorService implementation.
   679      */
   680      */
   680     private static class DelegatedExecutorService
   681     private static class DelegatedExecutorService
   681             extends AbstractExecutorService {
   682             implements ExecutorService {
   682         private final ExecutorService e;
   683         private final ExecutorService e;
   683         DelegatedExecutorService(ExecutorService executor) { e = executor; }
   684         DelegatedExecutorService(ExecutorService executor) { e = executor; }
   684         public void execute(Runnable command) { e.execute(command); }
   685         public void execute(Runnable command) {
       
   686             try {
       
   687                 e.execute(command);
       
   688             } finally { reachabilityFence(this); }
       
   689         }
   685         public void shutdown() { e.shutdown(); }
   690         public void shutdown() { e.shutdown(); }
   686         public List<Runnable> shutdownNow() { return e.shutdownNow(); }
   691         public List<Runnable> shutdownNow() {
   687         public boolean isShutdown() { return e.isShutdown(); }
   692             try {
   688         public boolean isTerminated() { return e.isTerminated(); }
   693                 return e.shutdownNow();
       
   694             } finally { reachabilityFence(this); }
       
   695         }
       
   696         public boolean isShutdown() {
       
   697             try {
       
   698                 return e.isShutdown();
       
   699             } finally { reachabilityFence(this); }
       
   700         }
       
   701         public boolean isTerminated() {
       
   702             try {
       
   703                 return e.isTerminated();
       
   704             } finally { reachabilityFence(this); }
       
   705         }
   689         public boolean awaitTermination(long timeout, TimeUnit unit)
   706         public boolean awaitTermination(long timeout, TimeUnit unit)
   690             throws InterruptedException {
   707             throws InterruptedException {
   691             return e.awaitTermination(timeout, unit);
   708             try {
       
   709                 return e.awaitTermination(timeout, unit);
       
   710             } finally { reachabilityFence(this); }
   692         }
   711         }
   693         public Future<?> submit(Runnable task) {
   712         public Future<?> submit(Runnable task) {
   694             return e.submit(task);
   713             try {
       
   714                 return e.submit(task);
       
   715             } finally { reachabilityFence(this); }
   695         }
   716         }
   696         public <T> Future<T> submit(Callable<T> task) {
   717         public <T> Future<T> submit(Callable<T> task) {
   697             return e.submit(task);
   718             try {
       
   719                 return e.submit(task);
       
   720             } finally { reachabilityFence(this); }
   698         }
   721         }
   699         public <T> Future<T> submit(Runnable task, T result) {
   722         public <T> Future<T> submit(Runnable task, T result) {
   700             return e.submit(task, result);
   723             try {
       
   724                 return e.submit(task, result);
       
   725             } finally { reachabilityFence(this); }
   701         }
   726         }
   702         public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
   727         public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
   703             throws InterruptedException {
   728             throws InterruptedException {
   704             return e.invokeAll(tasks);
   729             try {
       
   730                 return e.invokeAll(tasks);
       
   731             } finally { reachabilityFence(this); }
   705         }
   732         }
   706         public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
   733         public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
   707                                              long timeout, TimeUnit unit)
   734                                              long timeout, TimeUnit unit)
   708             throws InterruptedException {
   735             throws InterruptedException {
   709             return e.invokeAll(tasks, timeout, unit);
   736             try {
       
   737                 return e.invokeAll(tasks, timeout, unit);
       
   738             } finally { reachabilityFence(this); }
   710         }
   739         }
   711         public <T> T invokeAny(Collection<? extends Callable<T>> tasks)
   740         public <T> T invokeAny(Collection<? extends Callable<T>> tasks)
   712             throws InterruptedException, ExecutionException {
   741             throws InterruptedException, ExecutionException {
   713             return e.invokeAny(tasks);
   742             try {
       
   743                 return e.invokeAny(tasks);
       
   744             } finally { reachabilityFence(this); }
   714         }
   745         }
   715         public <T> T invokeAny(Collection<? extends Callable<T>> tasks,
   746         public <T> T invokeAny(Collection<? extends Callable<T>> tasks,
   716                                long timeout, TimeUnit unit)
   747                                long timeout, TimeUnit unit)
   717             throws InterruptedException, ExecutionException, TimeoutException {
   748             throws InterruptedException, ExecutionException, TimeoutException {
   718             return e.invokeAny(tasks, timeout, unit);
   749             try {
       
   750                 return e.invokeAny(tasks, timeout, unit);
       
   751             } finally { reachabilityFence(this); }
   719         }
   752         }
   720     }
   753     }
   721 
   754 
   722     private static class FinalizableDelegatedExecutorService
   755     private static class FinalizableDelegatedExecutorService
   723             extends DelegatedExecutorService {
   756             extends DelegatedExecutorService {