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; |
14 |
|
|
15 |
|
/** |
16 |
|
* Factory and utility methods for {@link Executor}, {@link |
17 |
< |
* ExecutorService}, {@link Future}, and {@link Cancellable} classes |
18 |
< |
* defined in this package. |
17 |
> |
* ExecutorService}, {@link ThreadFactory}, {@link Future}, and {@link |
18 |
> |
* Cancellable} classes defined in this package. |
19 |
|
* |
20 |
|
* @since 1.5 |
21 |
|
* @author Doug Lea |
274 |
|
executor.execute(future); |
275 |
|
return future; |
276 |
|
} |
276 |
– |
|
277 |
|
|
278 |
|
private static class PrivilegedActionAdapter implements Callable<Object> { |
279 |
|
PrivilegedActionAdapter(PrivilegedAction action) { |
295 |
|
private final PrivilegedExceptionAction action; |
296 |
|
} |
297 |
|
|
298 |
+ |
/** |
299 |
+ |
* Return a default thread factory used to create new threads. |
300 |
+ |
* This factory creates all new threads used by an Executor in the |
301 |
+ |
* same {@link ThreadGroup}. If there is a {@link |
302 |
+ |
* java.lang.SecurityManager}, it uses the group of {@link |
303 |
+ |
* System#getSecurityManager}, else the group of the thread |
304 |
+ |
* invoking this <tt>defaultThreadFactory</tt> method. Each new |
305 |
+ |
* thread is created as a non-daemon thread with priority |
306 |
+ |
* <tt>Thread.NORM_PRIORITY</tt>. New threads have names |
307 |
+ |
* accessible via {@link Thread#getName} of |
308 |
+ |
* <em>pool-N-thread-M</em>, where <em>N</em> is the sequence |
309 |
+ |
* number of this factory, and <em>M</em> is the sequence number |
310 |
+ |
* of the thread created by this factory. |
311 |
+ |
* @return the thread factory |
312 |
+ |
*/ |
313 |
+ |
public static ThreadFactory defaultThreadFactory() { |
314 |
+ |
return new DefaultThreadFactory(); |
315 |
+ |
} |
316 |
+ |
|
317 |
+ |
/** |
318 |
+ |
* Return a default thread factory used to create new threads. |
319 |
+ |
* This factory creates threads with the same settings as {@link |
320 |
+ |
* Executors#defaultThreadFactory}, additionally setting the |
321 |
+ |
* AccessControlContext and contextClassLoader of new threads to |
322 |
+ |
* be the same as the thread invoking this |
323 |
+ |
* <tt>privilegedThreadFactory</tt> method. A new |
324 |
+ |
* <tt>privilegedThreadFactory</tt> can be created within an |
325 |
+ |
* {@link AccessController#doPrivileged} action to create |
326 |
+ |
* threads with the selected permission settings holding within |
327 |
+ |
* that action. Alternatively, a factory can be used to create |
328 |
+ |
* threads with any available access control context by first |
329 |
+ |
* setting them in the current thread, and then invoking this |
330 |
+ |
* method. |
331 |
+ |
* |
332 |
+ |
* <p> Note that while tasks running within such threads will have |
333 |
+ |
* the same access control and class loader settings as the |
334 |
+ |
* current thread, they need not have the same {@link |
335 |
+ |
* java.lang.ThreadLocal} or {@link |
336 |
+ |
* java.lang.InheritableThreadLocal} values. If necessary, |
337 |
+ |
* particular values of thread locals can be set or reset before |
338 |
+ |
* any task runs in {@link ThreadPoolExecutor} subclasses using |
339 |
+ |
* {@link ThreadPoolExecutor#beforeExecute}. Also, if it is |
340 |
+ |
* necessary to initialize worker threads to have the same |
341 |
+ |
* InheritableThreadLocal settings as some other designated |
342 |
+ |
* thread, you can create a custom ThreadFactory in which that |
343 |
+ |
* thread waits for and services requests to create others that |
344 |
+ |
* will inherit its values. |
345 |
+ |
* |
346 |
+ |
* @return the thread factory |
347 |
+ |
* @throws AccessControlException if the current access control |
348 |
+ |
* context does not have permission to both get and set context |
349 |
+ |
* class loader. |
350 |
+ |
* @see PrivilegedFutureTask |
351 |
+ |
*/ |
352 |
+ |
public static ThreadFactory privilegedThreadFactory() { |
353 |
+ |
return new PrivilegedThreadFactory(); |
354 |
+ |
} |
355 |
+ |
|
356 |
+ |
static class DefaultThreadFactory implements ThreadFactory { |
357 |
+ |
static final AtomicInteger poolNumber = new AtomicInteger(1); |
358 |
+ |
final ThreadGroup group; |
359 |
+ |
final AtomicInteger threadNumber = new AtomicInteger(1); |
360 |
+ |
final String namePrefix; |
361 |
+ |
|
362 |
+ |
DefaultThreadFactory() { |
363 |
+ |
SecurityManager s = System.getSecurityManager(); |
364 |
+ |
group = (s != null)? s.getThreadGroup() : |
365 |
+ |
Thread.currentThread().getThreadGroup(); |
366 |
+ |
namePrefix = "pool-" + |
367 |
+ |
poolNumber.getAndIncrement() + |
368 |
+ |
"-thread-"; |
369 |
+ |
} |
370 |
+ |
|
371 |
+ |
public Thread newThread(Runnable r) { |
372 |
+ |
Thread t = new Thread(group, r, |
373 |
+ |
namePrefix + threadNumber.getAndIncrement(), |
374 |
+ |
0); |
375 |
+ |
if (t.isDaemon()) |
376 |
+ |
t.setDaemon(false); |
377 |
+ |
if (t.getPriority() != Thread.NORM_PRIORITY) |
378 |
+ |
t.setPriority(Thread.NORM_PRIORITY); |
379 |
+ |
return t; |
380 |
+ |
} |
381 |
+ |
} |
382 |
+ |
|
383 |
+ |
static class PrivilegedThreadFactory extends DefaultThreadFactory { |
384 |
+ |
private final ClassLoader ccl; |
385 |
+ |
private final AccessControlContext acc; |
386 |
+ |
|
387 |
+ |
PrivilegedThreadFactory() { |
388 |
+ |
super(); |
389 |
+ |
this.ccl = Thread.currentThread().getContextClassLoader(); |
390 |
+ |
this.acc = AccessController.getContext(); |
391 |
+ |
acc.checkPermission(new RuntimePermission("setContextClassLoader")); |
392 |
+ |
} |
393 |
+ |
|
394 |
+ |
public Thread newThread(final Runnable r) { |
395 |
+ |
return super.newThread(new Runnable() { |
396 |
+ |
public void run() { |
397 |
+ |
AccessController.doPrivileged(new PrivilegedAction() { |
398 |
+ |
public Object run() { |
399 |
+ |
Thread.currentThread().setContextClassLoader(ccl); |
400 |
+ |
r.run(); |
401 |
+ |
return null; |
402 |
+ |
} |
403 |
+ |
}, acc); |
404 |
+ |
} |
405 |
+ |
}); |
406 |
+ |
} |
407 |
+ |
|
408 |
+ |
} |
409 |
+ |
|
410 |
|
|
411 |
|
/** Cannot instantiate. */ |
412 |
|
private Executors() {} |