ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/Executors.java
Revision: 1.35
Committed: Thu Dec 11 19:08:03 2003 UTC (20 years, 5 months ago) by dl
Branch: MAIN
Changes since 1.34: +24 -76 lines
Log Message:
Remove internal delegation wrappers

File Contents

# Content
1 /*
2 * Written by Doug Lea with assistance from members of JCP JSR-166
3 * Expert Group and released to the public domain. Use, modify, and
4 * redistribute this code in any way without acknowledgement.
5 */
6
7 package java.util.concurrent;
8 import java.util.*;
9 import java.util.concurrent.atomic.AtomicInteger;
10 import java.security.AccessControlContext;
11 import java.security.AccessController;
12 import java.security.PrivilegedAction;
13 import java.security.PrivilegedExceptionAction;
14
15 /**
16 * Factory and utility methods for {@link Executor}, {@link
17 * ExecutorService}, and {@link ThreadFactory} classes defined in this
18 * package.
19 *
20 * @since 1.5
21 * @author Doug Lea
22 */
23 public class Executors {
24
25 /**
26 * Creates a thread pool that reuses a fixed set of threads
27 * operating off a shared unbounded queue. If any thread
28 * terminates due to a failure during execution prior to shutdown,
29 * a new one will take its place if needed to execute subsequent
30 * tasks.
31 *
32 * @param nThreads the number of threads in the pool
33 * @return the newly created thread pool
34 */
35 public static ExecutorService newFixedThreadPool(int nThreads) {
36 return new ThreadPoolExecutor(nThreads, nThreads,
37 0L, TimeUnit.MILLISECONDS,
38 new LinkedBlockingQueue<Runnable>());
39 }
40
41 /**
42 * Creates a thread pool that reuses a fixed set of threads
43 * operating off a shared unbounded queue, using the provided
44 * ThreadFactory to create new threads when needed.
45 *
46 * @param nThreads the number of threads in the pool
47 * @param threadFactory the factory to use when creating new threads
48 * @return the newly created thread pool
49 */
50 public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) {
51 return new ThreadPoolExecutor(nThreads, nThreads,
52 0L, TimeUnit.MILLISECONDS,
53 new LinkedBlockingQueue<Runnable>(),
54 threadFactory);
55 }
56
57 /**
58 * Creates an Executor that uses a single worker thread operating
59 * off an unbounded queue. (Note however that if this single
60 * thread terminates due to a failure during execution prior to
61 * shutdown, a new one will take its place if needed to execute
62 * subsequent tasks.) Tasks are guaranteed to execute
63 * sequentially, and no more than one task will be active at any
64 * given time. This method is equivalent in effect to
65 *<tt>new FixedThreadPool(1)</tt>.
66 *
67 * @return the newly-created single-threaded Executor
68 */
69 public static ExecutorService newSingleThreadExecutor() {
70 return new ThreadPoolExecutor(1, 1,
71 0L, TimeUnit.MILLISECONDS,
72 new LinkedBlockingQueue<Runnable>());
73 }
74
75 /**
76 * Creates an Executor that uses a single worker thread operating
77 * off an unbounded queue, and uses the provided ThreadFactory to
78 * create new threads when needed.
79 * @param threadFactory the factory to use when creating new
80 * threads
81 *
82 * @return the newly-created single-threaded Executor
83 */
84 public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) {
85 return new ThreadPoolExecutor(1, 1,
86 0L, TimeUnit.MILLISECONDS,
87 new LinkedBlockingQueue<Runnable>(),
88 threadFactory);
89 }
90
91 /**
92 * Creates a thread pool that creates new threads as needed, but
93 * will reuse previously constructed threads when they are
94 * available. These pools will typically improve the performance
95 * of programs that execute many short-lived asynchronous tasks.
96 * Calls to <tt>execute</tt> will reuse previously constructed
97 * threads if available. If no existing thread is available, a new
98 * thread will be created and added to the pool. Threads that have
99 * not been used for sixty seconds are terminated and removed from
100 * the cache. Thus, a pool that remains idle for long enough will
101 * not consume any resources. Note that pools with similar
102 * properties but different details (for example, timeout parameters)
103 * may be created using {@link ThreadPoolExecutor} constructors.
104 *
105 * @return the newly created thread pool
106 */
107 public static ExecutorService newCachedThreadPool() {
108 return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
109 60, TimeUnit.SECONDS,
110 new SynchronousQueue<Runnable>());
111 }
112
113 /**
114 * Creates a thread pool that creates new threads as needed, but
115 * will reuse previously constructed threads when they are
116 * available, and uses the provided
117 * ThreadFactory to create new threads when needed.
118 * @param threadFactory the factory to use when creating new threads
119 * @return the newly created thread pool
120 */
121 public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) {
122 return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
123 60, TimeUnit.SECONDS,
124 new SynchronousQueue<Runnable>(),
125 threadFactory);
126 }
127
128 /**
129 * Creates a thread pool that can schedule commands to run after a
130 * given delay, or to execute periodically.
131 * @return a newly created scheduled thread pool with termination management
132 */
133 public static ScheduledExecutorService newScheduledThreadPool() {
134 return newScheduledThreadPool(1);
135 }
136
137 /**
138 * Creates a thread pool that can schedule commands to run after a
139 * given delay, or to execute periodically.
140 * @param corePoolSize the number of threads to keep in the pool,
141 * even if they are idle.
142 * @return a newly created scheduled thread pool with termination management
143 */
144 public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
145 return new ScheduledThreadPoolExecutor(corePoolSize);
146 }
147
148 /**
149 * Creates a thread pool that can schedule commands to run after a
150 * given delay, or to execute periodically.
151 * @param corePoolSize the number of threads to keep in the pool,
152 * even if they are idle.
153 * @param threadFactory the factory to use when the executor
154 * creates a new thread.
155 * @return a newly created scheduled thread pool with termination management
156 */
157 public static ScheduledExecutorService newScheduledThreadPool(
158 int corePoolSize, ThreadFactory threadFactory) {
159 return new ScheduledThreadPoolExecutor(corePoolSize, threadFactory);
160 }
161
162 /**
163 * Return a default thread factory used to create new threads.
164 * This factory creates all new threads used by an Executor in the
165 * same {@link ThreadGroup}. If there is a {@link
166 * java.lang.SecurityManager}, it uses the group of {@link
167 * System#getSecurityManager}, else the group of the thread
168 * invoking this <tt>defaultThreadFactory</tt> method. Each new
169 * thread is created as a non-daemon thread with priority
170 * <tt>Thread.NORM_PRIORITY</tt>. New threads have names
171 * accessible via {@link Thread#getName} of
172 * <em>pool-N-thread-M</em>, where <em>N</em> is the sequence
173 * number of this factory, and <em>M</em> is the sequence number
174 * of the thread created by this factory.
175 * @return the thread factory
176 */
177 public static ThreadFactory defaultThreadFactory() {
178 return new DefaultThreadFactory();
179 }
180
181 /**
182 * Return a thread factory used to create new threads that
183 * have the same permissions as the current thread.
184 * This factory creates threads with the same settings as {@link
185 * Executors#defaultThreadFactory}, additionally setting the
186 * AccessControlContext and contextClassLoader of new threads to
187 * be the same as the thread invoking this
188 * <tt>privilegedThreadFactory</tt> method. A new
189 * <tt>privilegedThreadFactory</tt> can be created within an
190 * {@link AccessController#doPrivileged} action setting the
191 * current thread's access control context to create threads with
192 * the selected permission settings holding within that action.
193 *
194 * <p> Note that while tasks running within such threads will have
195 * the same access control and class loader settings as the
196 * current thread, they need not have the same {@link
197 * java.lang.ThreadLocal} or {@link
198 * java.lang.InheritableThreadLocal} values. If necessary,
199 * particular values of thread locals can be set or reset before
200 * any task runs in {@link ThreadPoolExecutor} subclasses using
201 * {@link ThreadPoolExecutor#beforeExecute}. Also, if it is
202 * necessary to initialize worker threads to have the same
203 * InheritableThreadLocal settings as some other designated
204 * thread, you can create a custom ThreadFactory in which that
205 * thread waits for and services requests to create others that
206 * will inherit its values.
207 *
208 * @return the thread factory
209 * @throws AccessControlException if the current access control
210 * context does not have permission to both get and set context
211 * class loader.
212 * @see PrivilegedFutureTask
213 */
214 public static ThreadFactory privilegedThreadFactory() {
215 return new PrivilegedThreadFactory();
216 }
217
218 static class DefaultThreadFactory implements ThreadFactory {
219 static final AtomicInteger poolNumber = new AtomicInteger(1);
220 final ThreadGroup group;
221 final AtomicInteger threadNumber = new AtomicInteger(1);
222 final String namePrefix;
223
224 DefaultThreadFactory() {
225 SecurityManager s = System.getSecurityManager();
226 group = (s != null)? s.getThreadGroup() :
227 Thread.currentThread().getThreadGroup();
228 namePrefix = "pool-" +
229 poolNumber.getAndIncrement() +
230 "-thread-";
231 }
232
233 public Thread newThread(Runnable r) {
234 Thread t = new Thread(group, r,
235 namePrefix + threadNumber.getAndIncrement(),
236 0);
237 if (t.isDaemon())
238 t.setDaemon(false);
239 if (t.getPriority() != Thread.NORM_PRIORITY)
240 t.setPriority(Thread.NORM_PRIORITY);
241 return t;
242 }
243 }
244
245 static class PrivilegedThreadFactory extends DefaultThreadFactory {
246 private final ClassLoader ccl;
247 private final AccessControlContext acc;
248
249 PrivilegedThreadFactory() {
250 super();
251 this.ccl = Thread.currentThread().getContextClassLoader();
252 this.acc = AccessController.getContext();
253 acc.checkPermission(new RuntimePermission("setContextClassLoader"));
254 }
255
256 public Thread newThread(final Runnable r) {
257 return super.newThread(new Runnable() {
258 public void run() {
259 AccessController.doPrivileged(new PrivilegedAction() {
260 public Object run() {
261 Thread.currentThread().setContextClassLoader(ccl);
262 r.run();
263 return null;
264 }
265 }, acc);
266 }
267 });
268 }
269
270 }
271
272
273 /** Cannot instantiate. */
274 private Executors() {}
275 }