OpenJDK类加载实现浅析#3:并行加载

今天来看下OpenJDK类加载中关于并行加载的一些代码。还是一样要分别看看类加载库跟虚拟机,因为二者在这方面仍然是需要配合完成的。

类加载库所做的工作

在JDK7之前,方法是synchronized的,

protected synchronized Class<?> loadClass(String name, boolean resolve)

也就是说,类加载的时候,直接是要锁住整个classloader的。

到了JDK7,这个地方终于做出了优化,直接来看下方法的代码,

protected Class<?> loadClass(String name, boolean resolve)throws ClassNotFoundException{synchronized (getClassLoadingLock(name)) {// First, check if the class has already been loadedClass c = findLoadedClass(name);if (c == null) {long t0 = System.nanoTime();try {if (parent != null) {c = parent.loadClass(name, false);} else {c = findBootstrapClassOrNull(name);}} catch (ClassNotFoundException e) {// ClassNotFoundException thrown if class not found// from the non-null parent class loader}if (c == null) {t1 = System.nanoTime();c = findClass(name);// this is the defining class loader; record the statssun.misc.PerfCounter.getParentDelegationTime().addTime(t1 – t0);sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);sun.misc.PerfCounter.getFindClasses().increment();}}if (resolve) {resolveClass(c);}return c;}}

改成了同步由getClassLoadingLock(name)返回的对象,看看这个方法,

/*** Returns the lock object for class loading operations.* For backward compatibility, the default implementation of this method* behaves as follows. If this ClassLoader object is registered as* parallel capable, the method returns a dedicated object associated* with the specified class name. Otherwise, the method returns this* ClassLoader object. </p>** @param className*The name of the to-be-loaded class** @return the lock for class loading operations** @throws NullPointerException*If registered as parallel capable and <tt>className</tt> is null** @see #loadClass(String, boolean)** @since 1.7*/protected Object getClassLoadingLock(String className) {Object lock = this; //// 向后兼容if (parallelLockMap != null) {Object newLock = new Object();lock = parallelLockMap.putIfAbsent(className, newLock);if (lock == null) {lock = newLock;}}return lock;}

将要进行加载的类的类名映射到一个new出来的Object,对这个Object进行同步相当于给正在加载的类加锁了。所以其实是通过减小锁的粒度来进行了优化。

在JDK7的类库中,可以看到好多classloader都会调用,这个方法是用来告诉虚拟机,这个classloader是支持并行加载的。虚拟机怎么使用的我们下面会说到,先来看看这个方法做了啥,

/*** Registers the caller as parallel capable.</p>* The registration succeeds if and only if all of the following* conditions are met: <br>* 1. no instance of the caller has been created</p>* 2. all of the super classes (except class Object) of the caller are* registered as parallel capable</p>* Note that once a class loader is registered as parallel capable, there* is no way to change it back. </p>** @return true if the caller is successfully registered as*parallel capable and false if otherwise.** @since 1.7*/() {Class<? extends ClassLoader> callerClass =Reflection.getCallerClass().asSubclass(ClassLoader.class);return ParallelLoaders.register(callerClass);} /*** Encapsulates the set of parallel capable loader types.*/{private ParallelLoaders() {}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())) {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);}}}旅行,重复一个承诺和梦想,听他第二十八次提起童年往事,

OpenJDK类加载实现浅析#3:并行加载

相关文章:

你感兴趣的文章:

标签云: