< 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 >