1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/Executors.java Sat Mar 19 10:46:31 2016 +0100
1.3 @@ -0,0 +1,706 @@
1.4 +/*
1.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
1.6 + *
1.7 + * This code is free software; you can redistribute it and/or modify it
1.8 + * under the terms of the GNU General Public License version 2 only, as
1.9 + * published by the Free Software Foundation. Oracle designates this
1.10 + * particular file as subject to the "Classpath" exception as provided
1.11 + * by Oracle in the LICENSE file that accompanied this code.
1.12 + *
1.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
1.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
1.16 + * version 2 for more details (a copy is included in the LICENSE file that
1.17 + * accompanied this code).
1.18 + *
1.19 + * You should have received a copy of the GNU General Public License version
1.20 + * 2 along with this work; if not, write to the Free Software Foundation,
1.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
1.22 + *
1.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
1.24 + * or visit www.oracle.com if you need additional information or have any
1.25 + * questions.
1.26 + */
1.27 +
1.28 +/*
1.29 + * This file is available under and governed by the GNU General Public
1.30 + * License version 2 only, as published by the Free Software Foundation.
1.31 + * However, the following notice accompanied the original version of this
1.32 + * file:
1.33 + *
1.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
1.35 + * Expert Group and released to the public domain, as explained at
1.36 + * http://creativecommons.org/publicdomain/zero/1.0/
1.37 + */
1.38 +
1.39 +package java.util.concurrent;
1.40 +import java.util.*;
1.41 +import java.util.concurrent.atomic.AtomicInteger;
1.42 +import java.security.AccessControlContext;
1.43 +import java.security.AccessController;
1.44 +import java.security.PrivilegedAction;
1.45 +import java.security.PrivilegedExceptionAction;
1.46 +import java.security.PrivilegedActionException;
1.47 +import java.security.AccessControlException;
1.48 +import sun.security.util.SecurityConstants;
1.49 +
1.50 +/**
1.51 + * Factory and utility methods for {@link Executor}, {@link
1.52 + * ExecutorService}, {@link ScheduledExecutorService}, {@link
1.53 + * ThreadFactory}, and {@link Callable} classes defined in this
1.54 + * package. This class supports the following kinds of methods:
1.55 + *
1.56 + * <ul>
1.57 + * <li> Methods that create and return an {@link ExecutorService}
1.58 + * set up with commonly useful configuration settings.
1.59 + * <li> Methods that create and return a {@link ScheduledExecutorService}
1.60 + * set up with commonly useful configuration settings.
1.61 + * <li> Methods that create and return a "wrapped" ExecutorService, that
1.62 + * disables reconfiguration by making implementation-specific methods
1.63 + * inaccessible.
1.64 + * <li> Methods that create and return a {@link ThreadFactory}
1.65 + * that sets newly created threads to a known state.
1.66 + * <li> Methods that create and return a {@link Callable}
1.67 + * out of other closure-like forms, so they can be used
1.68 + * in execution methods requiring <tt>Callable</tt>.
1.69 + * </ul>
1.70 + *
1.71 + * @since 1.5
1.72 + * @author Doug Lea
1.73 + */
1.74 +public class Executors {
1.75 +
1.76 + /**
1.77 + * Creates a thread pool that reuses a fixed number of threads
1.78 + * operating off a shared unbounded queue. At any point, at most
1.79 + * <tt>nThreads</tt> threads will be active processing tasks.
1.80 + * If additional tasks are submitted when all threads are active,
1.81 + * they will wait in the queue until a thread is available.
1.82 + * If any thread terminates due to a failure during execution
1.83 + * prior to shutdown, a new one will take its place if needed to
1.84 + * execute subsequent tasks. The threads in the pool will exist
1.85 + * until it is explicitly {@link ExecutorService#shutdown shutdown}.
1.86 + *
1.87 + * @param nThreads the number of threads in the pool
1.88 + * @return the newly created thread pool
1.89 + * @throws IllegalArgumentException if {@code nThreads <= 0}
1.90 + */
1.91 + public static ExecutorService newFixedThreadPool(int nThreads) {
1.92 + return new ThreadPoolExecutor(nThreads, nThreads,
1.93 + 0L, TimeUnit.MILLISECONDS,
1.94 + new LinkedBlockingQueue<Runnable>());
1.95 + }
1.96 +
1.97 + /**
1.98 + * Creates a thread pool that reuses a fixed number of threads
1.99 + * operating off a shared unbounded queue, using the provided
1.100 + * ThreadFactory to create new threads when needed. At any point,
1.101 + * at most <tt>nThreads</tt> threads will be active processing
1.102 + * tasks. If additional tasks are submitted when all threads are
1.103 + * active, they will wait in the queue until a thread is
1.104 + * available. If any thread terminates due to a failure during
1.105 + * execution prior to shutdown, a new one will take its place if
1.106 + * needed to execute subsequent tasks. The threads in the pool will
1.107 + * exist until it is explicitly {@link ExecutorService#shutdown
1.108 + * shutdown}.
1.109 + *
1.110 + * @param nThreads the number of threads in the pool
1.111 + * @param threadFactory the factory to use when creating new threads
1.112 + * @return the newly created thread pool
1.113 + * @throws NullPointerException if threadFactory is null
1.114 + * @throws IllegalArgumentException if {@code nThreads <= 0}
1.115 + */
1.116 + public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) {
1.117 + return new ThreadPoolExecutor(nThreads, nThreads,
1.118 + 0L, TimeUnit.MILLISECONDS,
1.119 + new LinkedBlockingQueue<Runnable>(),
1.120 + threadFactory);
1.121 + }
1.122 +
1.123 + /**
1.124 + * Creates an Executor that uses a single worker thread operating
1.125 + * off an unbounded queue. (Note however that if this single
1.126 + * thread terminates due to a failure during execution prior to
1.127 + * shutdown, a new one will take its place if needed to execute
1.128 + * subsequent tasks.) Tasks are guaranteed to execute
1.129 + * sequentially, and no more than one task will be active at any
1.130 + * given time. Unlike the otherwise equivalent
1.131 + * <tt>newFixedThreadPool(1)</tt> the returned executor is
1.132 + * guaranteed not to be reconfigurable to use additional threads.
1.133 + *
1.134 + * @return the newly created single-threaded Executor
1.135 + */
1.136 + public static ExecutorService newSingleThreadExecutor() {
1.137 + return new FinalizableDelegatedExecutorService
1.138 + (new ThreadPoolExecutor(1, 1,
1.139 + 0L, TimeUnit.MILLISECONDS,
1.140 + new LinkedBlockingQueue<Runnable>()));
1.141 + }
1.142 +
1.143 + /**
1.144 + * Creates an Executor that uses a single worker thread operating
1.145 + * off an unbounded queue, and uses the provided ThreadFactory to
1.146 + * create a new thread when needed. Unlike the otherwise
1.147 + * equivalent <tt>newFixedThreadPool(1, threadFactory)</tt> the
1.148 + * returned executor is guaranteed not to be reconfigurable to use
1.149 + * additional threads.
1.150 + *
1.151 + * @param threadFactory the factory to use when creating new
1.152 + * threads
1.153 + *
1.154 + * @return the newly created single-threaded Executor
1.155 + * @throws NullPointerException if threadFactory is null
1.156 + */
1.157 + public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) {
1.158 + return new FinalizableDelegatedExecutorService
1.159 + (new ThreadPoolExecutor(1, 1,
1.160 + 0L, TimeUnit.MILLISECONDS,
1.161 + new LinkedBlockingQueue<Runnable>(),
1.162 + threadFactory));
1.163 + }
1.164 +
1.165 + /**
1.166 + * Creates a thread pool that creates new threads as needed, but
1.167 + * will reuse previously constructed threads when they are
1.168 + * available. These pools will typically improve the performance
1.169 + * of programs that execute many short-lived asynchronous tasks.
1.170 + * Calls to <tt>execute</tt> will reuse previously constructed
1.171 + * threads if available. If no existing thread is available, a new
1.172 + * thread will be created and added to the pool. Threads that have
1.173 + * not been used for sixty seconds are terminated and removed from
1.174 + * the cache. Thus, a pool that remains idle for long enough will
1.175 + * not consume any resources. Note that pools with similar
1.176 + * properties but different details (for example, timeout parameters)
1.177 + * may be created using {@link ThreadPoolExecutor} constructors.
1.178 + *
1.179 + * @return the newly created thread pool
1.180 + */
1.181 + public static ExecutorService newCachedThreadPool() {
1.182 + return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
1.183 + 60L, TimeUnit.SECONDS,
1.184 + new SynchronousQueue<Runnable>());
1.185 + }
1.186 +
1.187 + /**
1.188 + * Creates a thread pool that creates new threads as needed, but
1.189 + * will reuse previously constructed threads when they are
1.190 + * available, and uses the provided
1.191 + * ThreadFactory to create new threads when needed.
1.192 + * @param threadFactory the factory to use when creating new threads
1.193 + * @return the newly created thread pool
1.194 + * @throws NullPointerException if threadFactory is null
1.195 + */
1.196 + public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) {
1.197 + return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
1.198 + 60L, TimeUnit.SECONDS,
1.199 + new SynchronousQueue<Runnable>(),
1.200 + threadFactory);
1.201 + }
1.202 +
1.203 + /**
1.204 + * Creates a single-threaded executor that can schedule commands
1.205 + * to run after a given delay, or to execute periodically.
1.206 + * (Note however that if this single
1.207 + * thread terminates due to a failure during execution prior to
1.208 + * shutdown, a new one will take its place if needed to execute
1.209 + * subsequent tasks.) Tasks are guaranteed to execute
1.210 + * sequentially, and no more than one task will be active at any
1.211 + * given time. Unlike the otherwise equivalent
1.212 + * <tt>newScheduledThreadPool(1)</tt> the returned executor is
1.213 + * guaranteed not to be reconfigurable to use additional threads.
1.214 + * @return the newly created scheduled executor
1.215 + */
1.216 + public static ScheduledExecutorService newSingleThreadScheduledExecutor() {
1.217 + return new DelegatedScheduledExecutorService
1.218 + (new ScheduledThreadPoolExecutor(1));
1.219 + }
1.220 +
1.221 + /**
1.222 + * Creates a single-threaded executor that can schedule commands
1.223 + * to run after a given delay, or to execute periodically. (Note
1.224 + * however that if this single thread terminates due to a failure
1.225 + * during execution prior to shutdown, a new one will take its
1.226 + * place if needed to execute subsequent tasks.) Tasks are
1.227 + * guaranteed to execute sequentially, and no more than one task
1.228 + * will be active at any given time. Unlike the otherwise
1.229 + * equivalent <tt>newScheduledThreadPool(1, threadFactory)</tt>
1.230 + * the returned executor is guaranteed not to be reconfigurable to
1.231 + * use additional threads.
1.232 + * @param threadFactory the factory to use when creating new
1.233 + * threads
1.234 + * @return a newly created scheduled executor
1.235 + * @throws NullPointerException if threadFactory is null
1.236 + */
1.237 + public static ScheduledExecutorService newSingleThreadScheduledExecutor(ThreadFactory threadFactory) {
1.238 + return new DelegatedScheduledExecutorService
1.239 + (new ScheduledThreadPoolExecutor(1, threadFactory));
1.240 + }
1.241 +
1.242 + /**
1.243 + * Creates a thread pool that can schedule commands to run after a
1.244 + * given delay, or to execute periodically.
1.245 + * @param corePoolSize the number of threads to keep in the pool,
1.246 + * even if they are idle.
1.247 + * @return a newly created scheduled thread pool
1.248 + * @throws IllegalArgumentException if {@code corePoolSize < 0}
1.249 + */
1.250 + public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
1.251 + return new ScheduledThreadPoolExecutor(corePoolSize);
1.252 + }
1.253 +
1.254 + /**
1.255 + * Creates a thread pool that can schedule commands to run after a
1.256 + * given delay, or to execute periodically.
1.257 + * @param corePoolSize the number of threads to keep in the pool,
1.258 + * even if they are idle.
1.259 + * @param threadFactory the factory to use when the executor
1.260 + * creates a new thread.
1.261 + * @return a newly created scheduled thread pool
1.262 + * @throws IllegalArgumentException if {@code corePoolSize < 0}
1.263 + * @throws NullPointerException if threadFactory is null
1.264 + */
1.265 + public static ScheduledExecutorService newScheduledThreadPool(
1.266 + int corePoolSize, ThreadFactory threadFactory) {
1.267 + return new ScheduledThreadPoolExecutor(corePoolSize, threadFactory);
1.268 + }
1.269 +
1.270 +
1.271 + /**
1.272 + * Returns an object that delegates all defined {@link
1.273 + * ExecutorService} methods to the given executor, but not any
1.274 + * other methods that might otherwise be accessible using
1.275 + * casts. This provides a way to safely "freeze" configuration and
1.276 + * disallow tuning of a given concrete implementation.
1.277 + * @param executor the underlying implementation
1.278 + * @return an <tt>ExecutorService</tt> instance
1.279 + * @throws NullPointerException if executor null
1.280 + */
1.281 + public static ExecutorService unconfigurableExecutorService(ExecutorService executor) {
1.282 + if (executor == null)
1.283 + throw new NullPointerException();
1.284 + return new DelegatedExecutorService(executor);
1.285 + }
1.286 +
1.287 + /**
1.288 + * Returns an object that delegates all defined {@link
1.289 + * ScheduledExecutorService} methods to the given executor, but
1.290 + * not any other methods that might otherwise be accessible using
1.291 + * casts. This provides a way to safely "freeze" configuration and
1.292 + * disallow tuning of a given concrete implementation.
1.293 + * @param executor the underlying implementation
1.294 + * @return a <tt>ScheduledExecutorService</tt> instance
1.295 + * @throws NullPointerException if executor null
1.296 + */
1.297 + public static ScheduledExecutorService unconfigurableScheduledExecutorService(ScheduledExecutorService executor) {
1.298 + if (executor == null)
1.299 + throw new NullPointerException();
1.300 + return new DelegatedScheduledExecutorService(executor);
1.301 + }
1.302 +
1.303 + /**
1.304 + * Returns a default thread factory used to create new threads.
1.305 + * This factory creates all new threads used by an Executor in the
1.306 + * same {@link ThreadGroup}. If there is a {@link
1.307 + * java.lang.SecurityManager}, it uses the group of {@link
1.308 + * System#getSecurityManager}, else the group of the thread
1.309 + * invoking this <tt>defaultThreadFactory</tt> method. Each new
1.310 + * thread is created as a non-daemon thread with priority set to
1.311 + * the smaller of <tt>Thread.NORM_PRIORITY</tt> and the maximum
1.312 + * priority permitted in the thread group. New threads have names
1.313 + * accessible via {@link Thread#getName} of
1.314 + * <em>pool-N-thread-M</em>, where <em>N</em> is the sequence
1.315 + * number of this factory, and <em>M</em> is the sequence number
1.316 + * of the thread created by this factory.
1.317 + * @return a thread factory
1.318 + */
1.319 + public static ThreadFactory defaultThreadFactory() {
1.320 + return new DefaultThreadFactory();
1.321 + }
1.322 +
1.323 + /**
1.324 + * Returns a thread factory used to create new threads that
1.325 + * have the same permissions as the current thread.
1.326 + * This factory creates threads with the same settings as {@link
1.327 + * Executors#defaultThreadFactory}, additionally setting the
1.328 + * AccessControlContext and contextClassLoader of new threads to
1.329 + * be the same as the thread invoking this
1.330 + * <tt>privilegedThreadFactory</tt> method. A new
1.331 + * <tt>privilegedThreadFactory</tt> can be created within an
1.332 + * {@link AccessController#doPrivileged} action setting the
1.333 + * current thread's access control context to create threads with
1.334 + * the selected permission settings holding within that action.
1.335 + *
1.336 + * <p> Note that while tasks running within such threads will have
1.337 + * the same access control and class loader settings as the
1.338 + * current thread, they need not have the same {@link
1.339 + * java.lang.ThreadLocal} or {@link
1.340 + * java.lang.InheritableThreadLocal} values. If necessary,
1.341 + * particular values of thread locals can be set or reset before
1.342 + * any task runs in {@link ThreadPoolExecutor} subclasses using
1.343 + * {@link ThreadPoolExecutor#beforeExecute}. Also, if it is
1.344 + * necessary to initialize worker threads to have the same
1.345 + * InheritableThreadLocal settings as some other designated
1.346 + * thread, you can create a custom ThreadFactory in which that
1.347 + * thread waits for and services requests to create others that
1.348 + * will inherit its values.
1.349 + *
1.350 + * @return a thread factory
1.351 + * @throws AccessControlException if the current access control
1.352 + * context does not have permission to both get and set context
1.353 + * class loader.
1.354 + */
1.355 + public static ThreadFactory privilegedThreadFactory() {
1.356 + return new PrivilegedThreadFactory();
1.357 + }
1.358 +
1.359 + /**
1.360 + * Returns a {@link Callable} object that, when
1.361 + * called, runs the given task and returns the given result. This
1.362 + * can be useful when applying methods requiring a
1.363 + * <tt>Callable</tt> to an otherwise resultless action.
1.364 + * @param task the task to run
1.365 + * @param result the result to return
1.366 + * @return a callable object
1.367 + * @throws NullPointerException if task null
1.368 + */
1.369 + public static <T> Callable<T> callable(Runnable task, T result) {
1.370 + if (task == null)
1.371 + throw new NullPointerException();
1.372 + return new RunnableAdapter<T>(task, result);
1.373 + }
1.374 +
1.375 + /**
1.376 + * Returns a {@link Callable} object that, when
1.377 + * called, runs the given task and returns <tt>null</tt>.
1.378 + * @param task the task to run
1.379 + * @return a callable object
1.380 + * @throws NullPointerException if task null
1.381 + */
1.382 + public static Callable<Object> callable(Runnable task) {
1.383 + if (task == null)
1.384 + throw new NullPointerException();
1.385 + return new RunnableAdapter<Object>(task, null);
1.386 + }
1.387 +
1.388 + /**
1.389 + * Returns a {@link Callable} object that, when
1.390 + * called, runs the given privileged action and returns its result.
1.391 + * @param action the privileged action to run
1.392 + * @return a callable object
1.393 + * @throws NullPointerException if action null
1.394 + */
1.395 + public static Callable<Object> callable(final PrivilegedAction<?> action) {
1.396 + if (action == null)
1.397 + throw new NullPointerException();
1.398 + return new Callable<Object>() {
1.399 + public Object call() { return action.run(); }};
1.400 + }
1.401 +
1.402 + /**
1.403 + * Returns a {@link Callable} object that, when
1.404 + * called, runs the given privileged exception action and returns
1.405 + * its result.
1.406 + * @param action the privileged exception action to run
1.407 + * @return a callable object
1.408 + * @throws NullPointerException if action null
1.409 + */
1.410 + public static Callable<Object> callable(final PrivilegedExceptionAction<?> action) {
1.411 + if (action == null)
1.412 + throw new NullPointerException();
1.413 + return new Callable<Object>() {
1.414 + public Object call() throws Exception { return action.run(); }};
1.415 + }
1.416 +
1.417 + /**
1.418 + * Returns a {@link Callable} object that will, when
1.419 + * called, execute the given <tt>callable</tt> under the current
1.420 + * access control context. This method should normally be
1.421 + * invoked within an {@link AccessController#doPrivileged} action
1.422 + * to create callables that will, if possible, execute under the
1.423 + * selected permission settings holding within that action; or if
1.424 + * not possible, throw an associated {@link
1.425 + * AccessControlException}.
1.426 + * @param callable the underlying task
1.427 + * @return a callable object
1.428 + * @throws NullPointerException if callable null
1.429 + *
1.430 + */
1.431 + public static <T> Callable<T> privilegedCallable(Callable<T> callable) {
1.432 + if (callable == null)
1.433 + throw new NullPointerException();
1.434 + return new PrivilegedCallable<T>(callable);
1.435 + }
1.436 +
1.437 + /**
1.438 + * Returns a {@link Callable} object that will, when
1.439 + * called, execute the given <tt>callable</tt> under the current
1.440 + * access control context, with the current context class loader
1.441 + * as the context class loader. This method should normally be
1.442 + * invoked within an {@link AccessController#doPrivileged} action
1.443 + * to create callables that will, if possible, execute under the
1.444 + * selected permission settings holding within that action; or if
1.445 + * not possible, throw an associated {@link
1.446 + * AccessControlException}.
1.447 + * @param callable the underlying task
1.448 + *
1.449 + * @return a callable object
1.450 + * @throws NullPointerException if callable null
1.451 + * @throws AccessControlException if the current access control
1.452 + * context does not have permission to both set and get context
1.453 + * class loader.
1.454 + */
1.455 + public static <T> Callable<T> privilegedCallableUsingCurrentClassLoader(Callable<T> callable) {
1.456 + if (callable == null)
1.457 + throw new NullPointerException();
1.458 + return new PrivilegedCallableUsingCurrentClassLoader<T>(callable);
1.459 + }
1.460 +
1.461 + // Non-public classes supporting the public methods
1.462 +
1.463 + /**
1.464 + * A callable that runs given task and returns given result
1.465 + */
1.466 + static final class RunnableAdapter<T> implements Callable<T> {
1.467 + final Runnable task;
1.468 + final T result;
1.469 + RunnableAdapter(Runnable task, T result) {
1.470 + this.task = task;
1.471 + this.result = result;
1.472 + }
1.473 + public T call() {
1.474 + task.run();
1.475 + return result;
1.476 + }
1.477 + }
1.478 +
1.479 + /**
1.480 + * A callable that runs under established access control settings
1.481 + */
1.482 + static final class PrivilegedCallable<T> implements Callable<T> {
1.483 + private final Callable<T> task;
1.484 + private final AccessControlContext acc;
1.485 +
1.486 + PrivilegedCallable(Callable<T> task) {
1.487 + this.task = task;
1.488 + this.acc = AccessController.getContext();
1.489 + }
1.490 +
1.491 + public T call() throws Exception {
1.492 + try {
1.493 + return AccessController.doPrivileged(
1.494 + new PrivilegedExceptionAction<T>() {
1.495 + public T run() throws Exception {
1.496 + return task.call();
1.497 + }
1.498 + }, acc);
1.499 + } catch (PrivilegedActionException e) {
1.500 + throw e.getException();
1.501 + }
1.502 + }
1.503 + }
1.504 +
1.505 + /**
1.506 + * A callable that runs under established access control settings and
1.507 + * current ClassLoader
1.508 + */
1.509 + static final class PrivilegedCallableUsingCurrentClassLoader<T> implements Callable<T> {
1.510 + private final Callable<T> task;
1.511 + private final AccessControlContext acc;
1.512 + private final ClassLoader ccl;
1.513 +
1.514 + PrivilegedCallableUsingCurrentClassLoader(Callable<T> task) {
1.515 + SecurityManager sm = System.getSecurityManager();
1.516 + if (sm != null) {
1.517 + // Calls to getContextClassLoader from this class
1.518 + // never trigger a security check, but we check
1.519 + // whether our callers have this permission anyways.
1.520 + sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
1.521 +
1.522 + // Whether setContextClassLoader turns out to be necessary
1.523 + // or not, we fail fast if permission is not available.
1.524 + sm.checkPermission(new RuntimePermission("setContextClassLoader"));
1.525 + }
1.526 + this.task = task;
1.527 + this.acc = AccessController.getContext();
1.528 + this.ccl = Thread.currentThread().getContextClassLoader();
1.529 + }
1.530 +
1.531 + public T call() throws Exception {
1.532 + try {
1.533 + return AccessController.doPrivileged(
1.534 + new PrivilegedExceptionAction<T>() {
1.535 + public T run() throws Exception {
1.536 + ClassLoader savedcl = null;
1.537 + Thread t = Thread.currentThread();
1.538 + try {
1.539 + ClassLoader cl = t.getContextClassLoader();
1.540 + if (ccl != cl) {
1.541 + t.setContextClassLoader(ccl);
1.542 + savedcl = cl;
1.543 + }
1.544 + return task.call();
1.545 + } finally {
1.546 + if (savedcl != null)
1.547 + t.setContextClassLoader(savedcl);
1.548 + }
1.549 + }
1.550 + }, acc);
1.551 + } catch (PrivilegedActionException e) {
1.552 + throw e.getException();
1.553 + }
1.554 + }
1.555 + }
1.556 +
1.557 + /**
1.558 + * The default thread factory
1.559 + */
1.560 + static class DefaultThreadFactory implements ThreadFactory {
1.561 + private static final AtomicInteger poolNumber = new AtomicInteger(1);
1.562 + private final ThreadGroup group;
1.563 + private final AtomicInteger threadNumber = new AtomicInteger(1);
1.564 + private final String namePrefix;
1.565 +
1.566 + DefaultThreadFactory() {
1.567 + SecurityManager s = System.getSecurityManager();
1.568 + group = (s != null) ? s.getThreadGroup() :
1.569 + Thread.currentThread().getThreadGroup();
1.570 + namePrefix = "pool-" +
1.571 + poolNumber.getAndIncrement() +
1.572 + "-thread-";
1.573 + }
1.574 +
1.575 + public Thread newThread(Runnable r) {
1.576 + Thread t = new Thread(group, r,
1.577 + namePrefix + threadNumber.getAndIncrement(),
1.578 + 0);
1.579 + if (t.isDaemon())
1.580 + t.setDaemon(false);
1.581 + if (t.getPriority() != Thread.NORM_PRIORITY)
1.582 + t.setPriority(Thread.NORM_PRIORITY);
1.583 + return t;
1.584 + }
1.585 + }
1.586 +
1.587 + /**
1.588 + * Thread factory capturing access control context and class loader
1.589 + */
1.590 + static class PrivilegedThreadFactory extends DefaultThreadFactory {
1.591 + private final AccessControlContext acc;
1.592 + private final ClassLoader ccl;
1.593 +
1.594 + PrivilegedThreadFactory() {
1.595 + super();
1.596 + SecurityManager sm = System.getSecurityManager();
1.597 + if (sm != null) {
1.598 + // Calls to getContextClassLoader from this class
1.599 + // never trigger a security check, but we check
1.600 + // whether our callers have this permission anyways.
1.601 + sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
1.602 +
1.603 + // Fail fast
1.604 + sm.checkPermission(new RuntimePermission("setContextClassLoader"));
1.605 + }
1.606 + this.acc = AccessController.getContext();
1.607 + this.ccl = Thread.currentThread().getContextClassLoader();
1.608 + }
1.609 +
1.610 + public Thread newThread(final Runnable r) {
1.611 + return super.newThread(new Runnable() {
1.612 + public void run() {
1.613 + AccessController.doPrivileged(new PrivilegedAction<Void>() {
1.614 + public Void run() {
1.615 + Thread.currentThread().setContextClassLoader(ccl);
1.616 + r.run();
1.617 + return null;
1.618 + }
1.619 + }, acc);
1.620 + }
1.621 + });
1.622 + }
1.623 + }
1.624 +
1.625 + /**
1.626 + * A wrapper class that exposes only the ExecutorService methods
1.627 + * of an ExecutorService implementation.
1.628 + */
1.629 + static class DelegatedExecutorService extends AbstractExecutorService {
1.630 + private final ExecutorService e;
1.631 + DelegatedExecutorService(ExecutorService executor) { e = executor; }
1.632 + public void execute(Runnable command) { e.execute(command); }
1.633 + public void shutdown() { e.shutdown(); }
1.634 + public List<Runnable> shutdownNow() { return e.shutdownNow(); }
1.635 + public boolean isShutdown() { return e.isShutdown(); }
1.636 + public boolean isTerminated() { return e.isTerminated(); }
1.637 + public boolean awaitTermination(long timeout, TimeUnit unit)
1.638 + throws InterruptedException {
1.639 + return e.awaitTermination(timeout, unit);
1.640 + }
1.641 + public Future<?> submit(Runnable task) {
1.642 + return e.submit(task);
1.643 + }
1.644 + public <T> Future<T> submit(Callable<T> task) {
1.645 + return e.submit(task);
1.646 + }
1.647 + public <T> Future<T> submit(Runnable task, T result) {
1.648 + return e.submit(task, result);
1.649 + }
1.650 + public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
1.651 + throws InterruptedException {
1.652 + return e.invokeAll(tasks);
1.653 + }
1.654 + public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
1.655 + long timeout, TimeUnit unit)
1.656 + throws InterruptedException {
1.657 + return e.invokeAll(tasks, timeout, unit);
1.658 + }
1.659 + public <T> T invokeAny(Collection<? extends Callable<T>> tasks)
1.660 + throws InterruptedException, ExecutionException {
1.661 + return e.invokeAny(tasks);
1.662 + }
1.663 + public <T> T invokeAny(Collection<? extends Callable<T>> tasks,
1.664 + long timeout, TimeUnit unit)
1.665 + throws InterruptedException, ExecutionException, TimeoutException {
1.666 + return e.invokeAny(tasks, timeout, unit);
1.667 + }
1.668 + }
1.669 +
1.670 + static class FinalizableDelegatedExecutorService
1.671 + extends DelegatedExecutorService {
1.672 + FinalizableDelegatedExecutorService(ExecutorService executor) {
1.673 + super(executor);
1.674 + }
1.675 + protected void finalize() {
1.676 + super.shutdown();
1.677 + }
1.678 + }
1.679 +
1.680 + /**
1.681 + * A wrapper class that exposes only the ScheduledExecutorService
1.682 + * methods of a ScheduledExecutorService implementation.
1.683 + */
1.684 + static class DelegatedScheduledExecutorService
1.685 + extends DelegatedExecutorService
1.686 + implements ScheduledExecutorService {
1.687 + private final ScheduledExecutorService e;
1.688 + DelegatedScheduledExecutorService(ScheduledExecutorService executor) {
1.689 + super(executor);
1.690 + e = executor;
1.691 + }
1.692 + public ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit) {
1.693 + return e.schedule(command, delay, unit);
1.694 + }
1.695 + public <V> ScheduledFuture<V> schedule(Callable<V> callable, long delay, TimeUnit unit) {
1.696 + return e.schedule(callable, delay, unit);
1.697 + }
1.698 + public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit) {
1.699 + return e.scheduleAtFixedRate(command, initialDelay, period, unit);
1.700 + }
1.701 + public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit) {
1.702 + return e.scheduleWithFixedDelay(command, initialDelay, delay, unit);
1.703 + }
1.704 + }
1.705 +
1.706 +
1.707 + /** Cannot instantiate. */
1.708 + private Executors() {}
1.709 +}