ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/ForkJoinWorkerThread.java
Revision: 1.82
Committed: Sun Dec 6 18:10:00 2020 UTC (3 years, 5 months ago) by jsr166
Branch: MAIN
Changes since 1.81: +1 -1 lines
Log Message:
ForkJoinWorkerThread(ThreadGroup group, ForkJoinPool pool): demote to package-private, for now

File Contents

# User Rev Content
1 jsr166 1.1 /*
2     * Written by Doug Lea with assistance from members of JCP JSR-166
3     * Expert Group and released to the public domain, as explained at
4 jsr166 1.46 * http://creativecommons.org/publicdomain/zero/1.0/
5 jsr166 1.1 */
6    
7     package java.util.concurrent;
8    
9 jsr166 1.74 import java.security.AccessController;
10     import java.security.PrivilegedAction;
11 dl 1.60
12 jsr166 1.1 /**
13 jsr166 1.40 * A thread managed by a {@link ForkJoinPool}, which executes
14     * {@link ForkJoinTask}s.
15     * This class is subclassable solely for the sake of adding
16     * functionality -- there are no overridable methods dealing with
17     * scheduling or execution. However, you can override initialization
18     * and termination methods surrounding the main task processing loop.
19     * If you do create such a subclass, you will also need to supply a
20 jsr166 1.57 * custom {@link ForkJoinPool.ForkJoinWorkerThreadFactory} to
21 jsr166 1.76 * {@linkplain ForkJoinPool#ForkJoinPool(int, ForkJoinWorkerThreadFactory,
22     * UncaughtExceptionHandler, boolean, int, int, int, Predicate, long, TimeUnit)
23     * use it} in a {@code ForkJoinPool}.
24 jsr166 1.1 *
25     * @since 1.7
26     * @author Doug Lea
27     */
28     public class ForkJoinWorkerThread extends Thread {
29     /*
30 dl 1.14 * ForkJoinWorkerThreads are managed by ForkJoinPools and perform
31 dl 1.52 * ForkJoinTasks. For explanation, see the internal documentation
32     * of class ForkJoinPool.
33 dl 1.55 *
34 dl 1.79 * This class just maintains links to its pool and WorkQueue.
35 jsr166 1.1 */
36    
37 dl 1.52 final ForkJoinPool pool; // the pool this thread works in
38 dl 1.56 final ForkJoinPool.WorkQueue workQueue; // work-stealing mechanics
39 dl 1.54
40     /**
41 dl 1.79 * Full nonpublic constructor.
42 jsr166 1.1 */
43 dl 1.79 ForkJoinWorkerThread(ThreadGroup group, ForkJoinPool pool,
44     boolean useSystemClassLoader, boolean isInnocuous) {
45     super(group, null, pool.nextWorkerThreadName(), 0L);
46     UncaughtExceptionHandler handler = (this.pool = pool).ueh;
47     this.workQueue = new ForkJoinPool.WorkQueue(this, isInnocuous);
48     super.setDaemon(true);
49     if (handler != null)
50     super.setUncaughtExceptionHandler(handler);
51     if (useSystemClassLoader)
52     super.setContextClassLoader(ClassLoader.getSystemClassLoader());
53 dl 1.14 }
54    
55 jsr166 1.1 /**
56 dl 1.79 * Creates a ForkJoinWorkerThread operating in the given thread group and
57     * pool.
58     *
59     * @param group if non-null, the thread group for this thread
60     * @param pool the pool this thread works in
61     * @throws NullPointerException if pool is null
62 jsr166 1.74 */
63 jsr166 1.82 /* TODO: protected */ ForkJoinWorkerThread(ThreadGroup group, ForkJoinPool pool) {
64 dl 1.79 this(group, pool, false, false);
65 jsr166 1.74 }
66    
67     /**
68 dl 1.79 * Creates a ForkJoinWorkerThread operating in the given pool.
69     *
70     * @param pool the pool this thread works in
71     * @throws NullPointerException if pool is null
72 dl 1.60 */
73 dl 1.79 protected ForkJoinWorkerThread(ForkJoinPool pool) {
74     this(null, pool, false, false);
75 dl 1.60 }
76    
77     /**
78 jsr166 1.1 * Returns the pool hosting this thread.
79     *
80     * @return the pool
81     */
82     public ForkJoinPool getPool() {
83     return pool;
84     }
85    
86     /**
87 jsr166 1.59 * Returns the unique index number of this thread in its pool.
88     * The returned value ranges from zero to the maximum number of
89     * threads (minus one) that may exist in the pool, and does not
90     * change during the lifetime of the thread. This method may be
91     * useful for applications that track status or collect results
92     * per-worker-thread rather than per-task.
93 jsr166 1.1 *
94     * @return the index number
95     */
96     public int getPoolIndex() {
97 dl 1.65 return workQueue.getPoolIndex();
98 dl 1.45 }
99    
100 jsr166 1.1 /**
101 dl 1.14 * Initializes internal state after construction but before
102     * processing any tasks. If you override this method, you must
103 jsr166 1.39 * invoke {@code super.onStart()} at the beginning of the method.
104 dl 1.14 * Initialization requires care: Most fields must have legal
105     * default values, to ensure that attempted accesses from other
106     * threads work correctly even before this thread starts
107     * processing tasks.
108 jsr166 1.1 */
109 dl 1.14 protected void onStart() {
110     }
111 jsr166 1.1
112     /**
113 dl 1.14 * Performs cleanup associated with termination of this worker
114     * thread. If you override this method, you must invoke
115     * {@code super.onTermination} at the end of the overridden method.
116 jsr166 1.4 *
117 dl 1.14 * @param exception the exception causing this thread to abort due
118     * to an unrecoverable error, or {@code null} if completed normally
119 jsr166 1.1 */
120 dl 1.14 protected void onTermination(Throwable exception) {
121 jsr166 1.1 }
122    
123     /**
124     * This method is required to be public, but should never be
125     * called explicitly. It performs the main run loop to execute
126 jsr166 1.40 * {@link ForkJoinTask}s.
127 jsr166 1.1 */
128     public void run() {
129 dl 1.79 Throwable exception = null;
130     ForkJoinPool p = pool;
131     ForkJoinPool.WorkQueue w = workQueue;
132     if (p != null && w != null) { // skip on failed initialization
133 dl 1.52 try {
134 dl 1.79 p.registerWorker(w);
135 dl 1.60 onStart();
136 dl 1.79 p.runWorker(w);
137 dl 1.52 } catch (Throwable ex) {
138 dl 1.60 exception = ex;
139 dl 1.52 } finally {
140 dl 1.60 try {
141     onTermination(exception);
142     } catch (Throwable ex) {
143     if (exception == null)
144     exception = ex;
145     } finally {
146 dl 1.79 p.deregisterWorker(this, exception);
147 dl 1.60 }
148     }
149     }
150     }
151    
152     /**
153     * A worker thread that has no permissions, is not a member of any
154 jsr166 1.74 * user-defined ThreadGroup, uses the system class loader as
155     * thread context class loader, and erases all ThreadLocals after
156 dl 1.60 * running each top-level task.
157     */
158     static final class InnocuousForkJoinWorkerThread extends ForkJoinWorkerThread {
159     /** The ThreadGroup for all InnocuousForkJoinWorkerThreads */
160     private static final ThreadGroup innocuousThreadGroup =
161 jsr166 1.75 AccessController.doPrivileged(new PrivilegedAction<>() {
162     public ThreadGroup run() {
163     ThreadGroup group = Thread.currentThread().getThreadGroup();
164     for (ThreadGroup p; (p = group.getParent()) != null; )
165     group = p;
166     return new ThreadGroup(
167     group, "InnocuousForkJoinWorkerThreadGroup");
168     }});
169 dl 1.60
170     InnocuousForkJoinWorkerThread(ForkJoinPool pool) {
171 dl 1.79 super(innocuousThreadGroup, pool, true, true);
172 dl 1.60 }
173    
174     @Override // to silently fail
175     public void setUncaughtExceptionHandler(UncaughtExceptionHandler x) { }
176    
177     @Override // paranoically
178     public void setContextClassLoader(ClassLoader cl) {
179 dl 1.78 if (cl != null && ClassLoader.getSystemClassLoader() != cl)
180 dl 1.77 throw new SecurityException("setContextClassLoader");
181 dl 1.60 }
182 jsr166 1.1 }
183     }