6902010: (cl) Delay initialization of ClassLoader.parallelLoaders
Reviewed-by: forax, mchung, valeriep
--- a/jdk/src/share/classes/java/lang/ClassLoader.java Mon Dec 07 12:24:57 2009 +0000
+++ b/jdk/src/share/classes/java/lang/ClassLoader.java Mon Dec 07 12:29:14 2009 +0000
@@ -175,15 +175,8 @@
public abstract class ClassLoader {
private static native void registerNatives();
-
- // Set of classes which are registered as parallel capable class loaders
- private static final Set<Class<? extends ClassLoader>> parallelLoaders
- = Collections.newSetFromMap(Collections.synchronizedMap
- (new WeakHashMap<Class<? extends ClassLoader>, Boolean>()));
-
static {
registerNatives();
- parallelLoaders.add(ClassLoader.class);
}
// The parent class loader for delegation
@@ -191,6 +184,52 @@
// must be added *after* it.
private final ClassLoader parent;
+ /**
+ * Encapsulates the set of parallel capable loader types.
+ */
+ private static class ParallelLoaders {
+ private ParallelLoaders() {}
+
+ // the set of parallel capable loader types
+ private static final Set<Class<? extends ClassLoader>> loaderTypes =
+ Collections.newSetFromMap(
+ new WeakHashMap<Class<? extends ClassLoader>, Boolean>());
+ static {
+ synchronized (loaderTypes) { loaderTypes.add(ClassLoader.class); }
+ }
+
+ /**
+ * Registers the given class loader type as parallel capabale.
+ * Returns {@code true} is successfully registered; {@code false} if
+ * loader's super class is not registered.
+ */
+ static boolean register(Class<? extends ClassLoader> c) {
+ synchronized (loaderTypes) {
+ if (loaderTypes.contains(c.getSuperclass())) {
+ // register the class loader as parallel capable
+ // if and only if all of its super classes are.
+ // Note: given current classloading sequence, if
+ // the immediate super class is parallel capable,
+ // all the super classes higher up must be too.
+ loaderTypes.add(c);
+ return true;
+ } else {
+ return false;
+ }
+ }
+ }
+
+ /**
+ * Returns {@code true} if the given class loader type is
+ * registered as parallel capable.
+ */
+ static boolean isRegistered(Class<? extends ClassLoader> c) {
+ synchronized (loaderTypes) {
+ return loaderTypes.contains(c);
+ }
+ }
+ }
+
// Maps class name to the corresponding lock object when the current
// class loader is parallel capable.
// Note: VM also uses this field to decide if the current class loader
@@ -237,7 +276,7 @@
private ClassLoader(Void unused, ClassLoader parent) {
this.parent = parent;
- if (parallelLoaders.contains(this.getClass())) {
+ if (ParallelLoaders.isRegistered(this.getClass())) {
parallelLockMap = new ConcurrentHashMap<String, Object>();
package2certs = new ConcurrentHashMap<String, Certificate[]>();
domains =
@@ -1194,24 +1233,7 @@
* @since 1.7
*/
protected static boolean registerAsParallelCapable() {
- Class<? extends ClassLoader> caller = getCaller(1);
- Class superCls = caller.getSuperclass();
- boolean result = false;
- // Explicit synchronization needed for composite action
- synchronized (parallelLoaders) {
- if (!parallelLoaders.contains(caller)) {
- if (parallelLoaders.contains(superCls)) {
- // register the immediate caller as parallel capable
- // if and only if all of its super classes are.
- // Note: given current classloading sequence, if
- // the immediate super class is parallel capable,
- // all the super classes higher up must be too.
- result = true;
- parallelLoaders.add(caller);
- }
- } else result = true;
- }
- return result;
+ return ParallelLoaders.register(getCaller(1));
}
/**
@@ -2174,4 +2196,3 @@
return sys;
}
}
-