< prev index next >

src/java.base/share/classes/java/util/concurrent/ForkJoinWorkerThread.java

Print this page
8246585: ForkJoin updates
Reviewed-by: martin

@@ -33,14 +33,12 @@
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 package java.util.concurrent;
 
-import java.security.AccessControlContext;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
-import java.security.ProtectionDomain;
 
 /**
  * A thread managed by a {@link ForkJoinPool}, which executes
  * {@link ForkJoinTask}s.
  * This class is subclassable solely for the sake of adding

@@ -60,70 +58,51 @@
     /*
      * ForkJoinWorkerThreads are managed by ForkJoinPools and perform
      * ForkJoinTasks. For explanation, see the internal documentation
      * of class ForkJoinPool.
      *
-     * This class just maintains links to its pool and WorkQueue.  The
-     * pool field is set immediately upon construction, but the
-     * workQueue field is not set until a call to registerWorker
-     * completes. This leads to a visibility race, that is tolerated
-     * by requiring that the workQueue field is only accessed by the
-     * owning thread.
-     *
-     * Support for (non-public) subclass InnocuousForkJoinWorkerThread
-     * requires that we break quite a lot of encapsulation (via helper
-     * methods in ThreadLocalRandom) both here and in the subclass to
-     * access and set Thread fields.
+     * This class just maintains links to its pool and WorkQueue.
      */
 
     final ForkJoinPool pool;                // the pool this thread works in
     final ForkJoinPool.WorkQueue workQueue; // work-stealing mechanics
 
-    /** An AccessControlContext supporting no privileges */
-    private static final AccessControlContext INNOCUOUS_ACC =
-        new AccessControlContext(
-            new ProtectionDomain[] { new ProtectionDomain(null, null) });
+    /**
+     * Full nonpublic constructor.
+     */
+    ForkJoinWorkerThread(ThreadGroup group, ForkJoinPool pool,
+                         boolean useSystemClassLoader, boolean isInnocuous) {
+        super(group, null, pool.nextWorkerThreadName(), 0L);
+        UncaughtExceptionHandler handler = (this.pool = pool).ueh;
+        this.workQueue = new ForkJoinPool.WorkQueue(this, isInnocuous);
+        super.setDaemon(true);
+        if (handler != null)
+            super.setUncaughtExceptionHandler(handler);
+        if (useSystemClassLoader)
+            super.setContextClassLoader(ClassLoader.getSystemClassLoader());
+    }
 
     /**
-     * Creates a ForkJoinWorkerThread operating in the given pool.
+     * Creates a ForkJoinWorkerThread operating in the given thread group and
+     * pool.
      *
+     * @param group if non-null, the thread group for this thread
      * @param pool the pool this thread works in
      * @throws NullPointerException if pool is null
      */
-    protected ForkJoinWorkerThread(ForkJoinPool pool) {
-        // Use a placeholder until a useful name can be set in registerWorker
-        super("aForkJoinWorkerThread");
-        this.pool = pool;
-        this.workQueue = pool.registerWorker(this);
+    /* TODO: protected */ ForkJoinWorkerThread(ThreadGroup group, ForkJoinPool pool) {
+        this(group, pool, false, false);
     }
 
     /**
-     * Version for use by the default pool.  Supports setting the
-     * context class loader.  This is a separate constructor to avoid
-     * affecting the protected constructor.
-     */
-    ForkJoinWorkerThread(ForkJoinPool pool, ClassLoader ccl) {
-        super("aForkJoinWorkerThread");
-        super.setContextClassLoader(ccl);
-        ThreadLocalRandom.setInheritedAccessControlContext(this, INNOCUOUS_ACC);
-        this.pool = pool;
-        this.workQueue = pool.registerWorker(this);
-    }
-
-    /**
-     * Version for InnocuousForkJoinWorkerThread.
-     */
-    ForkJoinWorkerThread(ForkJoinPool pool,
-                         ClassLoader ccl,
-                         ThreadGroup threadGroup,
-                         AccessControlContext acc) {
-        super(threadGroup, null, "aForkJoinWorkerThread");
-        super.setContextClassLoader(ccl);
-        ThreadLocalRandom.setInheritedAccessControlContext(this, acc);
-        ThreadLocalRandom.eraseThreadLocals(this); // clear before registering
-        this.pool = pool;
-        this.workQueue = pool.registerWorker(this);
+     * Creates a ForkJoinWorkerThread operating in the given pool.
+     *
+     * @param pool the pool this thread works in
+     * @throws NullPointerException if pool is null
+     */
+    protected ForkJoinWorkerThread(ForkJoinPool pool) {
+        this(null, pool, false, false);
     }
 
     /**
      * Returns the pool hosting this thread.
      *

@@ -174,34 +153,31 @@
      * This method is required to be public, but should never be
      * called explicitly. It performs the main run loop to execute
      * {@link ForkJoinTask}s.
      */
     public void run() {
-        if (workQueue.array == null) { // only run once
             Throwable exception = null;
+        ForkJoinPool p = pool;
+        ForkJoinPool.WorkQueue w = workQueue;
+        if (p != null && w != null) {   // skip on failed initialization
             try {
+                p.registerWorker(w);
                 onStart();
-                pool.runWorker(workQueue);
+                p.runWorker(w);
             } catch (Throwable ex) {
                 exception = ex;
             } finally {
                 try {
                     onTermination(exception);
                 } catch (Throwable ex) {
                     if (exception == null)
                         exception = ex;
                 } finally {
-                    pool.deregisterWorker(this, exception);
-                }
+                    p.deregisterWorker(this, exception);
             }
         }
     }
-
-    /**
-     * Non-public hook method for InnocuousForkJoinWorkerThread.
-     */
-    void afterTopLevelExec() {
     }
 
     /**
      * A worker thread that has no permissions, is not a member of any
      * user-defined ThreadGroup, uses the system class loader as

@@ -219,19 +195,11 @@
                     return new ThreadGroup(
                         group, "InnocuousForkJoinWorkerThreadGroup");
                 }});
 
         InnocuousForkJoinWorkerThread(ForkJoinPool pool) {
-            super(pool,
-                  ClassLoader.getSystemClassLoader(),
-                  innocuousThreadGroup,
-                  INNOCUOUS_ACC);
-        }
-
-        @Override // to erase ThreadLocals
-        void afterTopLevelExec() {
-            ThreadLocalRandom.eraseThreadLocals(this);
+            super(innocuousThreadGroup, pool, true, true);
         }
 
         @Override // to silently fail
         public void setUncaughtExceptionHandler(UncaughtExceptionHandler x) { }
 
< prev index next >