Skip to content

Commit

Permalink
Optimise the strategy we use to reset the classloader in the Common F…
Browse files Browse the repository at this point in the history
…orkJoin ThreadPool
  • Loading branch information
Sanne committed Jul 21, 2021
1 parent 3242590 commit ae9a634
Showing 1 changed file with 33 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,31 +20,42 @@ public class ForkJoinClassLoading {
* Really we should just not use the common pool at all.
*/
public static void setForkJoinClassLoader(ClassLoader classLoader) {
CountDownLatch allDone = new CountDownLatch(ForkJoinPool.getCommonPoolParallelism());
CountDownLatch taskRelease = new CountDownLatch(1);
for (int i = 0; i < ForkJoinPool.getCommonPoolParallelism(); ++i) {
ForkJoinPool.commonPool().execute(new Runnable() {
@Override
public void run() {
Thread.currentThread().setContextClassLoader(classLoader);
allDone.countDown();
try {
taskRelease.await();
} catch (InterruptedException e) {
log.error("Failed to set fork join ClassLoader", e);
final ForkJoinPool commonPool = ForkJoinPool.commonPool();

final int activeThreadCount = commonPool.getActiveThreadCount();

//The following approach is rather heavy, but there's good chances that there are actually no active threads,
//so skip it in this case.
//Additionally, if we can skip this this will prevent us from actually forcing to start all threads in the pool.
if (activeThreadCount > 0) {
//TODO we could theoretically improve this by using the system property java.util.concurrent.ForkJoinPool.common.threadFactory
//and force the common pool to register created threads so that we can reach and reset them.
CountDownLatch allDone = new CountDownLatch(ForkJoinPool.getCommonPoolParallelism());
CountDownLatch taskRelease = new CountDownLatch(1);
for (int i = 0; i < ForkJoinPool.getCommonPoolParallelism(); ++i) {
commonPool.execute(new Runnable() {
@Override
public void run() {
Thread.currentThread().setContextClassLoader(classLoader);
allDone.countDown();
try {
taskRelease.await();
} catch (InterruptedException e) {
log.error("Failed to set fork join ClassLoader", e);
}
}
});
}
try {
if (!allDone.await(1, TimeUnit.SECONDS)) {
log.error(
"Timed out trying to set fork join ClassLoader, this should never happen unless something has tied up a fork join thread before the app launched");
}
});
}
try {
if (!allDone.await(1, TimeUnit.SECONDS)) {
log.error(
"Timed out trying to set fork join ClassLoader, this should never happen unless something has tied up a fork join thread before the app launched");
} catch (InterruptedException e) {
log.error("Failed to set fork join ClassLoader", e);
} finally {
taskRelease.countDown();
}
} catch (InterruptedException e) {
log.error("Failed to set fork join ClassLoader", e);
} finally {
taskRelease.countDown();
}
}
}

0 comments on commit ae9a634

Please sign in to comment.