< prev index next >
src/java.base/share/classes/java/util/concurrent/ForkJoinWorkerThread.java
Print this page
8246585: ForkJoin updates
Reviewed-by: martin
*** 33,46 ****
* 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
--- 33,44 ----
*** 60,129 ****
/*
* 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.
*/
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) });
/**
! * 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) {
! // Use a placeholder until a useful name can be set in registerWorker
! super("aForkJoinWorkerThread");
! this.pool = pool;
! this.workQueue = pool.registerWorker(this);
}
/**
! * 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);
}
/**
* Returns the pool hosting this thread.
*
--- 58,108 ----
/*
* 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.
*/
final ForkJoinPool pool; // the pool this thread works in
final ForkJoinPool.WorkQueue workQueue; // work-stealing mechanics
! /**
! * 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 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
*/
! /* TODO: protected */ ForkJoinWorkerThread(ThreadGroup group, ForkJoinPool pool) {
! this(group, pool, false, false);
}
/**
! * 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,207 ****
* 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;
try {
onStart();
! pool.runWorker(workQueue);
} catch (Throwable ex) {
exception = ex;
} finally {
try {
onTermination(exception);
} catch (Throwable ex) {
if (exception == null)
exception = ex;
} finally {
! pool.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
--- 153,183 ----
* 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() {
Throwable exception = null;
+ ForkJoinPool p = pool;
+ ForkJoinPool.WorkQueue w = workQueue;
+ if (p != null && w != null) { // skip on failed initialization
try {
+ p.registerWorker(w);
onStart();
! p.runWorker(w);
} catch (Throwable ex) {
exception = ex;
} finally {
try {
onTermination(exception);
} catch (Throwable ex) {
if (exception == null)
exception = ex;
} finally {
! p.deregisterWorker(this, exception);
}
}
}
}
/**
* A worker thread that has no permissions, is not a member of any
* user-defined ThreadGroup, uses the system class loader as
*** 219,237 ****
return new ThreadGroup(
group, "InnocuousForkJoinWorkerThreadGroup");
}});
InnocuousForkJoinWorkerThread(ForkJoinPool pool) {
! super(pool,
! ClassLoader.getSystemClassLoader(),
! innocuousThreadGroup,
! INNOCUOUS_ACC);
! }
!
! @Override // to erase ThreadLocals
! void afterTopLevelExec() {
! ThreadLocalRandom.eraseThreadLocals(this);
}
@Override // to silently fail
public void setUncaughtExceptionHandler(UncaughtExceptionHandler x) { }
--- 195,205 ----
return new ThreadGroup(
group, "InnocuousForkJoinWorkerThreadGroup");
}});
InnocuousForkJoinWorkerThread(ForkJoinPool pool) {
! super(innocuousThreadGroup, pool, true, true);
}
@Override // to silently fail
public void setUncaughtExceptionHandler(UncaughtExceptionHandler x) { }
< prev index next >