ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/ForkJoinWorkerThread.java
Revision: 1.80
Committed: Tue Aug 11 20:56:30 2020 UTC (3 years, 9 months ago) by jsr166
Branch: MAIN
Changes since 1.79: +0 -1 lines
Log Message:
fix errorprone [RemoveUnusedImports]

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