双亲委派模型(观书有感)

一个类从加载到虚拟机开始,到卸载出内存为止,整个生命周期包括:加载、验证、准备、解析、初始化、使用、卸载七个阶段。
在这里插入图片描述
其中类加载器在这个过程中承担着非常重要的角色,而双亲委派模型便是实现类加载器的一种实现方式。

在这里插入图片描述
启动类加载器(无法被java程序直接引用):这个类加载器负责将存放在<JAVA_HOME>\lib目录中的或者是-XbootClassPath参数所指定的路径中的,并且是虚拟机识别的(按照文件名识别,例如rt.jar,名字不符合的文件,即使存在也不会被加载)类库加载到虚拟机中。
扩展类加载器:负责加载<JAVA_HOME>\lib\etc目录中的、或者被java.ext.dirs系统变量所指定的路径中的所有类库,开发者可以直接使用扩展类加载器
应用程序类加载器:这个类加载器是ClassLoader中getSystemClassLoader()方法的返回值,负责加载用户类路径ClassPath上所指定的类库,开发者可以直接使用这个类加载器,如果应用程序没有自定义过类加载器,那么默认这个就是程序的类加载器。

上图所展现的层级关系就是类加载器的双亲委派模型
双亲委派模型要求除了顶级的类加载器外,其余的类加载器都要有自己的父类加载器,注:他们之间父子关系一般不会以继承关系来实现,都是使用组合关系来复用父加载器的代码。
双亲委派模型工作过程
如果一个类加载器收到了类加载请求,他首先不会自己尝试加载这个类,而是把请求委派给父类加载器去完成,因此最终所有的请求都会到达顶层的启动类加载器去完成,只有当父类的加载器无法完成请求时(在他的搜索范围没有找到所需的类时),子类加载器会尝试自己去加载。

使用双亲委派模型的优点是
(1)双亲委派模型对java程序平稳运行作用非常大:
java类随着类加载一起具备了层级关系,例如:java.lang.Object、它存放在rt.jar中无论哪个类加载器去加载这个类,最终都会委派给启动类加载器去进行加载,相反,如果没有双亲委派模型,由各个类去自行加载的话,如果用户自定义了一个Object类,并放在ClassPath中,会导致程序变得混乱.
实现双亲委派代码在java.lang.ClassLoader的loadClass()方法中:

protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
    
    
    synchronized(this.getClassLoadingLock(name)) {
    
    
    //检查是否被加载过
        Class<?> c = this.findLoadedClass(name);
        if (c == null) {
    
    
            long t0 = System.nanoTime();

            try {
    
    
                if (this.parent != null) {
    
    
                    c = this.parent.loadClass(name, false);
                } else {
    
    
                    c = this.findBootstrapClassOrNull(name);
                }
            } catch (ClassNotFoundException var10) {
    
    
            //如果抛出ClassNotFoundException说明父类加载器无法完成类加载请求
            }

            if (c == null) {
    
    
            //父类加载器无法加载的情况下
            //调用本身的findClass方法来进行加载
                long t1 = System.nanoTime();
                c = this.findClass(name);
                PerfCounter.getParentDelegationTime().addTime(t1 - t0);
                PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
                PerfCounter.getFindClasses().increment();
            }
        }

        if (resolve) {
    
    
            this.resolveClass(c);
        }

        return c;
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_42163781/article/details/107979695