• 双亲委派模型


    类加载器介绍:
    从虚拟机的角度说,只存在两种类加载器:
    • 一种是启动类加载器,这个类加载器使用C++编写,是虚拟机自身的一部分;
    • 另一种是所有其他类的加载器,这些类加载器使用Java编写,独立于虚拟机,并且全部继承自抽象类java.lang.ClassLoader;
     
    从Java开发人员的角度看,类加载器可以细分为三种系统提供的类加载器:
    • 启动类加载器Bootstrap ClassLoader:这类加载器负责加Java_homelib目录中的或者-XBootclasspath路径指定的,并且是虚拟机识别的类库加载到虚拟机内存中。
    • 扩展类加载器Extension ClassLoader:这个加载器负责加载Java_homelibext目录中的或者有java.ext.dirs系统变量指定的路径下的类库,开发者可以直接使用扩展类加载器。
    • 应用程序类加载器Application ClassLoader:一般称为系统类加载器,它负责加载用户类路径上所指定的类库,开发者可以直接使用该类加载器,如果应用程序中没有自定义过自己的类加载器,一般情况下都是使用应用程序类加载器;
     
    双亲委派模型
    类加载器的双亲委托模型是JDK1.2被引入的。双亲委派模型不是一个强制性的约束模型,而是Java设计者推荐给开发者的一种类加载器实现方式。
                                                           
    如果上图所示的类加载器这种层次关系,称为类加载器的双亲委派模型。
    双亲委派模型要求除了顶层的“启动类加载器”外,其他的类加载器必须有自己的父类加载器。(这里所说的子类与父类,一般不是由继承方式实现的,而是通过组合关系来复用父加载器的代码)
     
    双亲委派模型的工作原理:
    如果一个类加载器收到了类加载的请求,它首先不会自己去尝试加载这个类,而是把这个请求委派给负责加载器去完成,每一层类加载器都是如此,因此所有的加载请求最终都应该传送到顶层的启动类加载器中,只由当父加载器反馈自己无法完成这个加载请求时,子加载器才会尝试自己去加载。
    双亲委派模型优点:Java类随着它的类加载器一起具备了一种带有优先级的层次关系,例如类java.lang.Object它存在在rt.jar之中,无论哪个类加载器要加载这个类,最终都会委派给处于模型顶层的启动类加载器进行加载,因此Object类在程序的各种类加载器环境中都是同一个类。相反,如果没有使用双亲委派模型,由各个类加载器自行去加载的话,如果用户自己编写一个java.lang.Object类并放在ClassPath中,那么系统中将会存在多个不同的Object类。
    双亲委派模式的具体实现在java.lang.Classloader类下的loadClass()方法中:
    protected Class<?> loadClass(String name, boolean resolve)
            throws ClassNotFoundException
        {
            synchronized (getClassLoadingLock(name)) {
                // 首先,检查这个类是否已经被加载过。
                Class<?> 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) {
                        // 如果父加载器或者启动类加载器无法加载的时候,再调用本身的findClass方法来进行类加载
                        long t1 = System.nanoTime();
                        c = findClass(name);
    
                        // this is the defining class loader; record the stats
                        sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
                        sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
                        sun.misc.PerfCounter.getFindClasses().increment();
                    }
                }
                if (resolve) {
                    resolveClass(c);
                }
                return c;
            }
    收藏文章数量从多到少与“把书读薄”是一个道理
  • 相关阅读:
    暑假日报-35
    非确定性有穷状态决策自动机练习题Vol.1 题解 & 总结
    loj数列分块入门 1~9
    第12周作业
    第二阶段考试
    UOJ NOI Round 4
    事件
    爬楼梯
    构造函数输出
    比较版本号大小
  • 原文地址:https://www.cnblogs.com/use-D/p/9749186.html
Copyright © 2020-2023  润新知