ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/ForkJoinWorkerThread.java
(Generate patch)

Comparing jsr166/src/main/java/util/concurrent/ForkJoinWorkerThread.java (file contents):
Revision 1.78 by dl, Thu Dec 13 15:56:09 2018 UTC vs.
Revision 1.79 by dl, Fri Jan 17 18:12:07 2020 UTC

# Line 33 | Line 33 | public class ForkJoinWorkerThread extend
33       * ForkJoinTasks. For explanation, see the internal documentation
34       * of class ForkJoinPool.
35       *
36 <     * This class just maintains links to its pool and WorkQueue.  The
37 <     * pool field is set immediately upon construction, but the
38 <     * workQueue field is not set until a call to registerWorker
39 <     * completes. This leads to a visibility race, that is tolerated
40 <     * by requiring that the workQueue field is only accessed by the
41 <     * owning thread.
42 <     *
43 <     * Support for (non-public) subclass InnocuousForkJoinWorkerThread
44 <     * requires that we break quite a lot of encapsulation (via helper
45 <     * methods in ThreadLocalRandom) both here and in the subclass to
46 <     * access and set Thread fields.
36 >     * This class just maintains links to its pool and WorkQueue.
37       */
38  
39      final ForkJoinPool pool;                // the pool this thread works in
40      final ForkJoinPool.WorkQueue workQueue; // work-stealing mechanics
41  
42      /**
43 <     * Creates a ForkJoinWorkerThread operating in the given pool.
54 <     *
55 <     * @param pool the pool this thread works in
56 <     * @throws NullPointerException if pool is null
43 >     * Full nonpublic constructor.
44       */
45 <    protected ForkJoinWorkerThread(ForkJoinPool pool) {
46 <        // Use a placeholder until a useful name can be set in registerWorker
47 <        super("aForkJoinWorkerThread");
48 <        this.pool = pool;
49 <        this.workQueue = pool.registerWorker(this);
45 >    ForkJoinWorkerThread(ThreadGroup group, ForkJoinPool pool,
46 >                         boolean useSystemClassLoader, boolean isInnocuous) {
47 >        super(group, null, pool.nextWorkerThreadName(), 0L);
48 >        UncaughtExceptionHandler handler = (this.pool = pool).ueh;
49 >        this.workQueue = new ForkJoinPool.WorkQueue(this, isInnocuous);
50 >        super.setDaemon(true);
51 >        if (handler != null)
52 >            super.setUncaughtExceptionHandler(handler);
53 >        if (useSystemClassLoader)
54 >            super.setContextClassLoader(ClassLoader.getSystemClassLoader());
55      }
56  
57      /**
58 <     * Version for use by the default pool.  Supports setting the
59 <     * context class loader.  This is a separate constructor to avoid
60 <     * affecting the protected constructor.
58 >     * Creates a ForkJoinWorkerThread operating in the given thread group and
59 >     * pool.
60 >     *
61 >     * @param group if non-null, the thread group for this thread
62 >     * @param pool the pool this thread works in
63 >     * @throws NullPointerException if pool is null
64       */
65 <    ForkJoinWorkerThread(ForkJoinPool pool, ClassLoader ccl) {
66 <        super("aForkJoinWorkerThread");
72 <        super.setContextClassLoader(ccl);
73 <        this.pool = pool;
74 <        this.workQueue = pool.registerWorker(this);
65 >    protected ForkJoinWorkerThread(ThreadGroup group, ForkJoinPool pool) {
66 >        this(group, pool, false, false);
67      }
68  
69      /**
70 <     * Version for InnocuousForkJoinWorkerThread.
70 >     * Creates a ForkJoinWorkerThread operating in the given pool.
71 >     *
72 >     * @param pool the pool this thread works in
73 >     * @throws NullPointerException if pool is null
74       */
75 <    ForkJoinWorkerThread(ForkJoinPool pool,
76 <                         ClassLoader ccl,
82 <                         ThreadGroup threadGroup,
83 <                         AccessControlContext acc) {
84 <        super(threadGroup, null, "aForkJoinWorkerThread");
85 <        super.setContextClassLoader(ccl);
86 <        ThreadLocalRandom.setInheritedAccessControlContext(this, acc);
87 <        ThreadLocalRandom.eraseThreadLocals(this); // clear before registering
88 <        this.pool = pool;
89 <        this.workQueue = pool.registerWorker(this);
75 >    protected ForkJoinWorkerThread(ForkJoinPool pool) {
76 >        this(null, pool, false, false);
77      }
78  
79      /**
# Line 141 | Line 128 | public class ForkJoinWorkerThread extend
128       * {@link ForkJoinTask}s.
129       */
130      public void run() {
131 <        if (workQueue.array == null) { // only run once
132 <            Throwable exception = null;
131 >        Throwable exception = null;
132 >        ForkJoinPool p = pool;
133 >        ForkJoinPool.WorkQueue w = workQueue;
134 >        if (p != null && w != null) {   // skip on failed initialization
135              try {
136 +                p.registerWorker(w);
137                  onStart();
138 <                pool.runWorker(workQueue);
138 >                p.runWorker(w);
139              } catch (Throwable ex) {
140                  exception = ex;
141              } finally {
# Line 155 | Line 145 | public class ForkJoinWorkerThread extend
145                      if (exception == null)
146                          exception = ex;
147                  } finally {
148 <                    pool.deregisterWorker(this, exception);
148 >                    p.deregisterWorker(this, exception);
149                  }
150              }
151          }
152      }
153  
154      /**
165     * Non-public hook method for InnocuousForkJoinWorkerThread.
166     */
167    void afterTopLevelExec() {
168    }
169
170    /**
155       * A worker thread that has no permissions, is not a member of any
156       * user-defined ThreadGroup, uses the system class loader as
157       * thread context class loader, and erases all ThreadLocals after
# Line 185 | Line 169 | public class ForkJoinWorkerThread extend
169                          group, "InnocuousForkJoinWorkerThreadGroup");
170                  }});
171  
188        /** An AccessControlContext supporting no privileges */
189        private static final AccessControlContext INNOCUOUS_ACC =
190            new AccessControlContext(
191                new ProtectionDomain[] { new ProtectionDomain(null, null) });
192
172          InnocuousForkJoinWorkerThread(ForkJoinPool pool) {
173 <            super(pool,
195 <                  ClassLoader.getSystemClassLoader(),
196 <                  innocuousThreadGroup,
197 <                  INNOCUOUS_ACC);
198 <        }
199 <
200 <        @Override // to erase ThreadLocals
201 <        void afterTopLevelExec() {
202 <            ThreadLocalRandom.eraseThreadLocals(this);
173 >            super(innocuousThreadGroup, pool, true, true);
174          }
175  
176          @Override // to silently fail

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines