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