8336707: Contention of ForkJoinPool grows when stealing works

Reviewed-by: vklang
This commit is contained in:
Doug Lea 2024-11-21 11:50:46 +00:00
parent f2b10c6c22
commit 18df6fd5ba
2 changed files with 422 additions and 346 deletions

View File

@ -41,6 +41,7 @@ import java.security.PrivilegedAction;
import java.security.ProtectionDomain;
import jdk.internal.access.JavaLangAccess;
import jdk.internal.access.SharedSecrets;
import jdk.internal.misc.Unsafe;
/**
* A thread managed by a {@link ForkJoinPool}, which executes
@ -225,6 +226,25 @@ public class ForkJoinWorkerThread extends Thread {
(sq = qs[i]) != null && sq.top - sq.base > 0) ||
q.top - q.base > 0));
}
/**
* Clears ThreadLocals, and if necessary resets ContextClassLoader
*/
final void resetThreadLocals() {
if (U.getReference(this, THREADLOCALS) != null)
U.putReference(this, THREADLOCALS, null);
if (U.getReference(this, INHERITABLETHREADLOCALS) != null)
U.putReference(this, INHERITABLETHREADLOCALS, null);
if ((this instanceof InnocuousForkJoinWorkerThread) &&
((InnocuousForkJoinWorkerThread)this).needCCLReset())
super.setContextClassLoader(ClassLoader.getSystemClassLoader());
}
private static final Unsafe U = Unsafe.getUnsafe();
private static final long THREADLOCALS
= U.objectFieldOffset(Thread.class, "threadLocals");
private static final long INHERITABLETHREADLOCALS
= U.objectFieldOffset(Thread.class, "inheritableThreadLocals");
private static final JavaLangAccess JLA = SharedSecrets.getJavaLangAccess();
/**
@ -236,6 +256,7 @@ public class ForkJoinWorkerThread extends Thread {
static final class InnocuousForkJoinWorkerThread extends ForkJoinWorkerThread {
/** The ThreadGroup for all InnocuousForkJoinWorkerThreads */
private static final ThreadGroup innocuousThreadGroup = createGroup();
private boolean resetCCL;
InnocuousForkJoinWorkerThread(ForkJoinPool pool) {
super(innocuousThreadGroup, pool, true, true);
}
@ -244,9 +265,20 @@ public class ForkJoinWorkerThread extends Thread {
public void setUncaughtExceptionHandler(UncaughtExceptionHandler x) { }
@Override // paranoically
@SuppressWarnings("removal")
public void setContextClassLoader(ClassLoader cl) {
if (cl != null && ClassLoader.getSystemClassLoader() != cl)
if (System.getSecurityManager() != null &&
cl != null && ClassLoader.getSystemClassLoader() != cl)
throw new SecurityException("setContextClassLoader");
resetCCL = true;
super.setContextClassLoader(cl);
}
final boolean needCCLReset() { // get and clear
boolean needReset;
if (needReset = resetCCL)
resetCCL = false;
return needReset;
}
static ThreadGroup createGroup() {
@ -255,5 +287,6 @@ public class ForkJoinWorkerThread extends Thread {
group = p;
return new ThreadGroup(group, "InnocuousForkJoinWorkerThreadGroup");
}
}
}