History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/java/util/concurrent/Executors.java (1 of 18352 files). Show all

Unified · Split

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