< prev index next >
src/java.base/share/classes/jdk/internal/ref/CleanerFactory.java
Print this page
@@ -23,26 +23,66 @@
* questions.
*/
package jdk.internal.ref;
+import jdk.internal.misc.InnocuousThread;
+
import java.lang.ref.Cleaner;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.atomic.AtomicInteger;
/**
* CleanerFactory provides a Cleaner for use within OpenJDK modules.
* The cleaner is created on the first reference to the CleanerFactory.
*/
public final class CleanerFactory {
/* The common Cleaner. */
- private final static Cleaner commonCleaner = Cleaner.create();
+ private final static Cleaner commonCleaner =
+ Cleaner.create(new InnocuousThreadFactory(false));
/**
- * Cleaner for use within OpenJDK modules.
+ * Cleaner for use within system modules.
+ *
+ * This Cleaner will run on a thread whose context class loader is null
+ * and system cleaner code has to handle null thread class loader.
*
- * @return a Cleaner for use within OpenJDK modules
+ * @return a Cleaner for use within system modules
*/
public static Cleaner cleaner() {
return commonCleaner;
}
+
+ /**
+ * A ThreadFactory for InnocuousThreads.
+ */
+ static final class InnocuousThreadFactory implements ThreadFactory {
+ private final boolean hasContextClassLoader;
+ InnocuousThreadFactory() {
+ this(true);
+ }
+
+ InnocuousThreadFactory(boolean hasTCCL) {
+ this.hasContextClassLoader = hasTCCL;
+ }
+
+ public Thread newThread(Runnable r) {
+ return AccessController.doPrivileged(new PrivilegedAction<Thread>() {
+ @Override
+ public Thread run() {
+ Thread t = new InnocuousThread(r, nextThreadName(), hasContextClassLoader);
+ t.setPriority(Thread.MAX_PRIORITY - 2);
+ return t;
+ }
+ });
+ }
+
+ final static AtomicInteger cleanerThreadNumber = new AtomicInteger();
+ static String nextThreadName() {
+ return "Cleaner-" + cleanerThreadNumber.getAndIncrement();
+ }
+ }
}
< prev index next >