Java 7 ClassLoader performance improvements

Use Java 7 `registerAsParallelCapable` and `getClassLoadingLock` methods
when possible. This should improve performance when running on JDK 7+
whilst still remaining JDK 6 compatible.

Closes gh-1284
pull/1280/merge
Phillip Webb 10 years ago
parent da5c36c3a9
commit 4f440fcbb9

@ -36,8 +36,19 @@ import org.springframework.boot.loader.jar.JarFile;
*/ */
public class LaunchedURLClassLoader extends URLClassLoader { public class LaunchedURLClassLoader extends URLClassLoader {
static {
try {
ClassLoader.registerAsParallelCapable();
}
catch (NoSuchMethodError ex) {
// Not available on earlier JDKs
}
}
private final ClassLoader rootClassLoader; private final ClassLoader rootClassLoader;
private final LockProvider lockProvider;
/** /**
* Create a new {@link LaunchedURLClassLoader} instance. * Create a new {@link LaunchedURLClassLoader} instance.
* @param urls the URLs from which to load classes and resources * @param urls the URLs from which to load classes and resources
@ -46,6 +57,17 @@ public class LaunchedURLClassLoader extends URLClassLoader {
public LaunchedURLClassLoader(URL[] urls, ClassLoader parent) { public LaunchedURLClassLoader(URL[] urls, ClassLoader parent) {
super(urls, parent); super(urls, parent);
this.rootClassLoader = findRootClassLoader(parent); this.rootClassLoader = findRootClassLoader(parent);
this.lockProvider = createLockProvider();
}
private LockProvider createLockProvider() {
try {
ClassLoader.class.getMethod("getClassLoadingLock", String.class);
return new Java7LockProvider();
}
catch (NoSuchMethodException ex) {
return new LockProvider();
}
} }
private ClassLoader findRootClassLoader(ClassLoader classLoader) { private ClassLoader findRootClassLoader(ClassLoader classLoader) {
@ -126,7 +148,7 @@ public class LaunchedURLClassLoader extends URLClassLoader {
@Override @Override
protected Class<?> loadClass(String name, boolean resolve) protected Class<?> loadClass(String name, boolean resolve)
throws ClassNotFoundException { throws ClassNotFoundException {
synchronized (this) { synchronized (this.lockProvider.getLock(this, name)) {
Class<?> loadedClass = findLoadedClass(name); Class<?> loadedClass = findLoadedClass(name);
if (loadedClass == null) { if (loadedClass == null) {
Handler.setUseFastConnectionExceptions(true); Handler.setUseFastConnectionExceptions(true);
@ -222,4 +244,27 @@ public class LaunchedURLClassLoader extends URLClassLoader {
} }
} }
/**
* Strategy used to provide the synchronize lock object to use when loading classes.
*/
private static class LockProvider {
public Object getLock(LaunchedURLClassLoader classLoader, String className) {
return classLoader;
}
}
/**
* Java 7 specific {@link LockProvider}.
*/
private static class Java7LockProvider extends LockProvider {
@Override
public Object getLock(LaunchedURLClassLoader classLoader, String className) {
return classLoader.getClassLoadingLock(className);
}
}
} }

Loading…
Cancel
Save