Java虚拟机类加载器之双亲委派机制模型案例

 更新时间:2021年08月03日 11:19:31   作者:洒家肉山大魔王  
这篇文章主要介绍了Java虚拟机类加载器之双亲委派机制模型案例,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下

1. 双亲委派模型是什么?

当某个类加载器需要加载某个.class字节码文件时,它首先把这个任务委托给它的上级类加载器,递归这个操作,如果上级的类加载器没有加载,自己才会去加载这个类。

2. 双亲委派模型的工作原理?

1.如果一个类加载器收到了类加载的请求,它首先不会自己去尝试加载这个类,而是把这个请求委派给父类加载器去执行;

2.如果父类加载器还存在其父类加载器,则进一步向上委托,依次递归,请求最终将到达顶层的启动类加载器;(每一个层次的类加载器都是如此,因此所有的加载请求最终都应该传送到最顶层的启动类加载器中。)

3.如果父类加载器可以完成类加载任务,就成功返回;倘若父类加载器反馈自己无法完成这个加载请求(它的搜索范围中没有找到所需的类)时,子加载器才会尝试自己去完成加载。

以上便是双亲委派模型的工作原理。

双亲委派模型对于保证Java程序的稳定运作极为重要,但它的实现却异常简单,用以实现双亲委
派的代码只有短短十余行,全部集中在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 {
                    //返回由引导类加载器加载的类;如果未找到,则返回 null。
                    c = findBootstrapClassOrNull(name);
                }
            } catch (ClassNotFoundException e) {
                // 如果父类加载器抛出ClassNotFoundException异常
                // 则说明父类加载器无法完成加载请求
            }
 
            if (c == null) {
                // 在父类加载器无法加载时
                // 再调用本身的findClass方法来进行加载
                long t1 = System.nanoTime();
                c = findClass(name);
 
                // 这是定义类加载器;记录统计数据
                sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
                sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
                sun.misc.PerfCounter.getFindClasses().increment();
            }
        }
        if (resolve) {
            resolveClass(c);
        }
        return c;
    }
}

这段源码逻辑:

1.首先,检查请求加载的类型是否已经被加载,倘若没有则调用父类加载器loadClass()方法;

2.如果父类加载器为空,则默认使用启动类加载器作为父加载器。

3.如果父类加载器加载失败,抛出ClassNotFoundException异常,这时候才调用自己的findClass()方法尝试进行加载。

可参考网上的双亲委派模型流程图:

3. 双亲委派机制的优势?

1.保证基础类仅加载一次,不会让JVM中存在重名的类。

防止重复加载同一个.class文件,比如String.class,每次加载都委托给父加载器,最终都是BootstrapClassLoader,都保证java核心类都是BootstrapClassLoader加载的,加载过了,就不用再加载一遍,保证了java的安全与稳定性。

2.保护程序安全,防止核心.class文件被随意篡改。

通过委托方式,不会去篡改核心.class,即使篡改也不会去加载,即使加载也不会是同一个.class对象了。不同的加载器加载同一个.class也不是同一个Class对象。这样保证了Class执行安全。

到此这篇关于Java虚拟机类加载器之双亲委派机制模型案例的文章就介绍到这了,更多相关Java虚拟机类加载器之双亲委派内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • java中Integer包装类装箱的一个细节详解

    java中Integer包装类装箱的一个细节详解

    Java中的Integer是int的包装类型,下面这篇文章主要给大家介绍了关于java中Integer包装类装箱的一个细节的相关资料,文中介绍的这个细节挺重要的,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起看看吧
    2018-07-07
  • 使用CORS实现JavaWeb跨域请求问题的方法

    使用CORS实现JavaWeb跨域请求问题的方法

    这篇文章主要介绍了使用Cors实现JavaWeb跨域请求问题的方法,非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2016-09-09
  • feign GET请求不支持对象传参的坑及解决

    feign GET请求不支持对象传参的坑及解决

    这篇文章主要介绍了feign GET请求不支持对象传参的坑及解决,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-03-03
  • Java集合系列之ArrayList源码分析

    Java集合系列之ArrayList源码分析

    这篇文章主要为大家详细介绍了Java集合系列之ArrayList源码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-02-02
  • MyBatis之传入参数为list、数组、map的写法

    MyBatis之传入参数为list、数组、map的写法

    这篇文章主要介绍了MyBatis之传入参数为list、数组、map的写法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-11-11
  • SpringBoot启动自动终止也不报错的原因及解决

    SpringBoot启动自动终止也不报错的原因及解决

    这篇文章主要介绍了SpringBoot启动自动终止也不报错的原因及解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-09-09
  • Spring boot 使用JdbcTemplate访问数据库

    Spring boot 使用JdbcTemplate访问数据库

    SpringBoot 是为了简化 Spring 应用的创建、运行、调试、部署等一系列问题而诞生的产物。本文重点给大家介绍spring boot 使用JdbcTemplate访问数据库,需要的朋友可以参考下
    2018-05-05
  • Java中的IP地址和InetAddress类使用详解

    Java中的IP地址和InetAddress类使用详解

    这篇文章主要介绍了Java中的IP地址和InetAddress类使用详解,是Java入门学习中的基础知识,需要的朋友可以参考下
    2015-10-10
  • 详解5种Java中常见限流算法

    详解5种Java中常见限流算法

    在高并发系统中,出于系统保护角度考虑,通常会对流量进行限流;不但在工作中要频繁使用,而且也是面试中的高频考点。本文就为大家整理了5种Java中常见限流算法,需要的可以参考一下
    2023-04-04
  • JAVA基本概念详解

    JAVA基本概念详解

    本文主要介绍了Java的基本概念。具有很好的参考价值,下面跟着小编一起来看下吧,希望能够给你带来帮助
    2021-11-11

最新评论