当前位置: 首页 > article >正文

java中双亲委派详解

什么是双亲委派机制?

双亲委派机制(Parent Delegation Model)是Java类加载器(ClassLoader)加载类时的一种策略。它的核心思想是:当一个类加载器收到加载类的请求时,不会立即自己加载,而是先将请求委派给父类加载器处理。只有当父类加载器无法完成加载时,子类加载器才会尝试自己加载。

1. 双亲委派机制的核心思想

双亲委派机制的核心思想可以用一句话概括:“先让父类加载器尝试加载类,父类加载器无法完成时,才由子类加载器自己加载。”

这种机制是一种层次化的类加载模型,每个类加载器都有一个父类加载器(除了顶层的Bootstrap ClassLoader)。类加载器在加载类时,会按照以下步骤进行:

  1. 委派:将加载请求委派给父类加载器。

  2. 检查:父类加载器检查是否已经加载过该类。

  3. 加载:如果父类加载器无法加载,子类加载器才会尝试加载。


2. 类加载器的层次结构

Java中的类加载器是一个树形结构,分为以下几层:

(1)Bootstrap ClassLoader(启动类加载器)

  • 职责:加载JVM核心类库(如java.lang.*java.util.*等),这些类库位于JAVA_HOME/lib目录下。

  • 特点

    • 由C++实现,是JVM的一部分。

    • 没有父类加载器(它是类加载器树的根节点)。

    • 无法在Java代码中直接获取(返回null)。

(2)Extension ClassLoader(扩展类加载器)

  • 职责:加载JAVA_HOME/lib/ext目录下的类库,或者由java.ext.dirs系统属性指定的目录。

  • 特点

    • 由Java实现,对应的类是sun.misc.Launcher$ExtClassLoader

    • 父类加载器是Bootstrap ClassLoader。

(3)Application ClassLoader(应用程序类加载器)

  • 职责:加载用户类路径(ClassPath)上的类库。

  • 特点

    • 由Java实现,对应的类是sun.misc.Launcher$AppClassLoader

    • 父类加载器是Extension ClassLoader。

    • 是默认的类加载器,负责加载用户编写的类。

(4)自定义类加载器

  • 职责:用户可以通过继承ClassLoader类,实现自定义的类加载逻辑。

  • 特点

    • 父类加载器通常是Application ClassLoader。

    • 可以打破双亲委派机制,实现特定的类加载需求。


3. 双亲委派的工作流程

当一个类加载器收到加载类的请求时,会按照以下步骤执行:

  1. 检查是否已加载

    • 类加载器首先检查自己是否已经加载过该类。如果已经加载,直接返回该类。

  2. 委派给父类加载器

    • 如果未加载,将加载请求委派给父类加载器。

    • 父类加载器重复同样的过程,继续向上委派,直到Bootstrap ClassLoader。

  3. 父类加载器尝试加载

    • 如果父类加载器能够加载该类,加载过程结束。

    • 如果父类加载器无法加载,子类加载器才会尝试自己加载。

  4. 子类加载器尝试加载

    • 如果子类加载器也无法加载,抛出ClassNotFoundException


4. 双亲委派的代码实现

双亲委派机制的实现主要在ClassLoader类的loadClass方法中。以下是简化版的源码分析:

protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {synchronized (getClassLoadingLock(name)) {// 1. 检查是否已经加载过该类Class<?> c = findLoadedClass(name);if (c == null) {try {// 2. 委派给父类加载器if (parent != null) {c = parent.loadClass(name, false);} else {// 如果父类加载器为null,说明是Bootstrap ClassLoaderc = findBootstrapClassOrNull(name);}} catch (ClassNotFoundException e) {// 父类加载器无法加载,忽略异常}// 3. 父类加载器无法加载时,自己尝试加载if (c == null) {c = findClass(name);}}// 4. 如果需要解析,解析该类if (resolve) {resolveClass(c);}return c;}
}

关键点:

  • findLoadedClass:检查是否已经加载过该类。

  • parent.loadClass:委派给父类加载器。

  • findClass:父类加载器无法加载时,自己尝试加载。


5. 双亲委派的优点

(1)避免重复加载

  • 由于类加载器会先委派给父类加载器,确保每个类只被加载一次,避免重复加载。

(2)安全性

  • 防止用户自定义的类替换核心类库中的类(如java.lang.String),确保核心类库的安全性。

(3)一致性

  • 保证同一个类在不同类加载器环境下的一致性。


6. 双亲委派的缺点

(1)灵活性不足

  • 在某些场景下,双亲委派机制可能不够灵活。例如:

    • 需要加载不同版本的类库。

    • 需要隔离不同模块的类加载环境。

(2)打破双亲委派

  • 在某些特殊场景下,可能需要打破双亲委派机制。例如:

    • Tomcat:每个Web应用使用独立的类加载器,避免类冲突。

    • OSGi:动态模块化系统,支持模块化加载和卸载。


7. 实际应用场景

(1)Tomcat的类加载器

  • Tomcat为每个Web应用提供了一个独立的类加载器(WebAppClassLoader),打破了双亲委派机制。

  • 这样做的目的是隔离不同Web应用的类加载环境,避免类冲突。

(2)OSGi框架

  • OSGi是一个动态模块化系统,每个模块(Bundle)有独立的类加载器。

  • OSGi通过复杂的类加载机制,支持模块的动态加载和卸载。

(3)SPI(Service Provider Interface)

  • Java的SPI机制(如JDBC)打破了双亲委派机制。

  • 例如,java.sql.Driver接口由Bootstrap ClassLoader加载,而具体的驱动实现(如com.mysql.cj.jdbc.Driver)由Application ClassLoader加载。


8. 总结

双亲委派机制是Java类加载的核心机制,通过层次化的委派方式,确保类的加载安全、一致且高效。它的主要优点包括避免重复加载、保证安全性和一致性,但在某些场景下可能不够灵活,需要打破双亲委派机制。

相关文章:

java中双亲委派详解

什么是双亲委派机制&#xff1f; 双亲委派机制&#xff08;Parent Delegation Model&#xff09;是Java类加载器&#xff08;ClassLoader&#xff09;加载类时的一种策略。它的核心思想是&#xff1a;当一个类加载器收到加载类的请求时&#xff0c;不会立即自己加载&#xff0…...

【Python爬虫(27)】探索数据可视化的魔法世界

【Python爬虫】专栏简介&#xff1a;本专栏是 Python 爬虫领域的集大成之作&#xff0c;共 100 章节。从 Python 基础语法、爬虫入门知识讲起&#xff0c;深入探讨反爬虫、多线程、分布式等进阶技术。以大量实例为支撑&#xff0c;覆盖网页、图片、音频等各类数据爬取&#xff…...

网络安全-js安全知识点与XSS常用payloads

简介 JavaScript 是一种轻量级的编程语言&#xff0c;定义了HTML的行为。它与Java的关系类似周杰和周杰伦的关系&#xff08;即没有关系&#xff09;。 用法 HTML 中的脚本必须位于 <script> 与 </script> 标签之间。 脚本可被放置在 HTML 页面的 <body>…...

ip属地是电话号码吗怎么改

在数字化时代&#xff0c;IP属地作为网络身份的一部分&#xff0c;对于许多互联网用户来说并不陌生。然而&#xff0c;关于IP属地的具体含义以及如何更改它&#xff0c;却常常让一些用户感到困惑。特别是当提到IP属地与电话号码之间的关系时&#xff0c;更是容易让人产生误解。…...

Ubuntu中使用yum命令出现错误提示:Command ‘yum‘ not found

Ubuntu中使用yum命令出现以下错误提示: 解决方法如下 1、使用su或sudo -s命令使普通用户切换为root用户 2、然后检测是否安装了build-essential程序包,输入命令: apt-get install build-essential 3、进度走完后安装yum,输入命令: apt-get install yum 如果成功安装&#xff…...

【Vue.js 和 React.js 的主要区别是什么?】

Vue.js 和 React.js 的主要区别是什么&#xff1f; 前言 Vue.js 和 React.js 是当前最流行的两个前端框架&#xff0c;它们都用于构建用户界面&#xff0c;但在设计理念、语法和使用方式上有显著差异。本文将从多个维度对比 Vue.js 和 React.js 的主要区别&#xff0c;帮助开…...

HarmonyOS NEXT 全栈开发实战手册(API 12+)

一、HarmonyOS NEXT 架构升级与关键技术 1.1 分布式能力增强&#xff08;重点标注&#xff09; 跨设备计算网格&#xff1a;支持动态分配 GPU/CPU/NPU 资源 // 分布式渲染示例&#xff08;API 12&#xff09; import renderService from ohos.distributedHardware.render; l…...

【rt-thread】rt-thread 控制 led 的两种方式

1. pin设备 #define LED_PIN 3int led(void) {rt_uint8_t count;rt_pin_mode(LED_PIN, PIN_MODE_OUTPUT); for(count 0 ; count < 10 ;count){ rt_pin_write(LED_PIN, PIN_HIGH);rt_kprintf("led on, count : %d %d\r\n", count, rt_pin_read(LED_PIN));…...

Python爬虫系列教程之第十三篇:构建高可用爬虫系统 —— 混合架构与自动化监控

大家好&#xff0c;欢迎继续关注本系列爬虫教程&#xff01;随着爬虫项目规模的不断扩大和业务需求的提升&#xff0c;单一技术方案往往难以满足实际应用中对高可用性、稳定性和自动化监控的要求。如何构建一个既能应对多种反爬策略&#xff0c;又能在异常情况下自动恢复、实时…...

picomax 中 rkipc 的main.c文件分析

main函数 int main(int argc, char **argv) {//wait_key_event 这个进程的pidpthread_t key_chk;LOG_DEBUG("main begin\n");//luckfox-pico/project/app/rkipc/rkipc/common/common.c中//显示版本rkipc_version_dump();//设置信号signal(SIGINT, sig_proc);signal(…...

深入理解 JVM 的栈帧结构

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家&#xff0c;历代文学网&#xff08;PC端可以访问&#xff1a;https://literature.sinhy.com/#/literature?__c1000&#xff0c;移动端可微信小程序搜索“历代文学”&#xff09;总架构师&#xff0c;15年工作经验&#xff0c;…...

[oeasy]python068_异常处理之后做些什么_try语句的完全体_最终_finally

068_异常处理之后做些什么_finally 异常处理之后做些什么_try语句的完全体_最终_finally 回忆上次内容 我们了解了 try 的细节 except 可以 捕获到异常 但报错比较简单 添加图片注释&#xff0c;不超过 140 字&#xff08;可选&#xff09; 游乐场里面的 报错 更全 更丰富 …...

数据库端性能测试优化案例

数据库端性能测试优化案例 数据库是系统性能的关键瓶颈之一&#xff0c;特别是在高并发、大数据量的场景下。以下是一些典型的数据库端性能测试优化案例&#xff0c;涵盖了查询优化、索引策略、连接池管理、分布式数据库设计等多个方面&#xff1a; 1. 案例&#xff1a;优化慢…...

如何实现使用DeepSeek的CV模型对管道内模糊、低光照或水渍干扰的图像进行去噪、超分辨率重建。...

要使用 DeepSeek 的 CV 模型对管道内模糊、低光照或水渍干扰的图像进行去噪、超分辨率重建&#xff0c;一般可以按照以下步骤实现&#xff1a; 1. 准备工作 1.1 获取 API 访问权限 首先&#xff0c;你需要从 DeepSeek 官方获取 API 访问权限和相应的 API 密钥。这通常需要在 De…...

PySide6学习专栏(四):用多线程完成复杂计算任务

如果计程序中要处理一个非常庞大的数据集中的数据&#xff0c;且数据处理计算很复杂&#xff0c;造成数据处理占用大量时间和CPU资源&#xff0c;如果不用多线程&#xff0c;仅在主进程中来处理数据&#xff0c;将会使整个程序卡死&#xff0c;必须采用多线程来处理这些数据是唯…...

神经网络八股(1)

1.什么是有监督学习&#xff0c;无监督学习 有监督学习是带有标签的&#xff0c;无监督学习是没有标签的&#xff0c;简单来说就是有监督学习的输入输出都是固定的&#xff0c;已知的&#xff0c;无监督学习输入是已知的&#xff0c;输出是不固定的&#xff0c;无监督学习是通…...

深度学习每周学习总结Y1(Yolov5 调用官方权重进行检测 )

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客Y1中的内容 &#x1f356; 原作者&#xff1a;K同学啊 | 接辅导、项目定制 ** 注意该训练营出现故意不退押金&#xff0c;恶意揣测偷懒用假的结果冒充真实打卡记录&#xff0c;在提出能够拿到视频录像…...

计算机视觉基础|从 OpenCV 到频域分析

一、引言 在当今数字化时代&#xff0c;图像处理已渗透到我们生活的方方面面&#xff0c;从日常使用的智能手机拍照美化&#xff0c;到医学领域的精准诊断&#xff0c;再到自动驾驶中的环境感知&#xff0c;其重要性不言而喻。在图像处理领域中&#xff0c;OpenCV 和频域分析&…...

74. 搜索二维矩阵(LeetCode 热题 100)

题目来源; 74. 搜索二维矩阵 - 力扣&#xff08;LeetCode&#xff09; 题目内容&#xff1a; 给你一个满足下述两条属性的 m x n 整数矩阵&#xff1a; 每行中的整数从左到右按非严格递增顺序排列。 每行的第一个整数大于前一行的最后一个整数。 给你一个整数 target &am…...

netcore libreoffice word转pdf中文乱码

一、效果 解决&#xff1a; cd /usr/share/fonts/ mkdir zhFont cd zhFont #windows系统C:\Windows\Fonts 中复制/usr/share/fonts/zhFont sudo apt update sudo apt install xfonts-utils mkfontscale mkfontdir #刷新字体缓存 fc-cache -fv #查看已安装的字体列表 fc-list :…...

qt-C++笔记之创建和初始化 `QGraphicsScene` 和 `QGraphicsView` 并关联视图和场景的方法

qt-C笔记之创建和初始化 QGraphicsScene 和 QGraphicsView 并关联视图和场景的方法 code review! 参考笔记 1.qt-C笔记之创建和初始化 QGraphicsScene 和 QGraphicsView 并关联视图和场景的方法 2.qt-C笔记之QGraphicsScene和 QGraphicsView中setScene、通过scene得到view、通过…...

OpenGL 01--构建GLFW、创建第一个工程、配置GLAD

一、OpenGL介绍 一般它被认为是一个API(Application Programming Interface, 应用程序编程接口)&#xff0c;包含了一系列可以操作图形、图像的函数。然而&#xff0c;OpenGL本身并不是一个API&#xff0c;它仅仅是一个由Khronos组织制定并维护的规范(Specification)。 OpenGL规…...

【时时三省】(C语言基础)求多项式1-1/2+1/3-1/4+...+1/99-1/100的值 用C语言表示

山不在高&#xff0c;有仙则名。水不在深&#xff0c;有龙则灵。 ----CSDN 时时三省 示例&#xff1a; 输出结果是 0.688172...

kafka-集群缩容

一. 简述&#xff1a; 当业务增加时&#xff0c;服务瓶颈&#xff0c;我们需要进行扩容。当业务量下降时&#xff0c;为成本考虑。自然也会涉及到缩容。假设集群有 15 台机器&#xff0c;预计缩到 10 台机器&#xff0c;那么需要做 5 次缩容操作&#xff0c;每次将一个节点下线…...

Ubuntu22.04 - etcd的安装和使用

目录 介绍安装Etcd安装etcd的客户端使用 介绍 Etcd 是一个 golang 编写的分布式、高可用的一致性键值存储系统&#xff0c;用于配置共享和服务发现等。它使用 Raft 一致性算法来保持集群数据的一致性&#xff0c;且客户端通过长连接watch 功能&#xff0c;能够及时收到数据变化…...

排查JVM的一些命令

查看JVM相关信息的方法 环境&#xff1a; Win10, jdk17 查看端口的Pid netstat -ano | findstr <端口号>列出当前运行的JVM进程 ## 用于输出JVM中运行的进程状态信息。通过jps&#xff0c;可以快速获取Java进程的PID&#xff08;进程标识符&#xff09;&#xff0c; …...

Apache Doris 实现毫秒级查询响应

1. 引言 1.1 数据分析的重要性 随着大数据时代的到来,企业对实时数据分析的需求日益增长。快速、准确地获取数据洞察成为企业在竞争中脱颖而出的关键。传统的数据库系统在处理大规模数据时往往面临性能瓶颈,难以满足实时分析的需求。例如,一个电商公司需要实时监控销售数据…...

Java 与设计模式(15):模板方法模式

一、定义 模板方法模式是一种行为设计模式&#xff0c;它定义了一个操作中的算法的骨架&#xff08;也就是大致的步骤和流程&#xff09;&#xff0c;而将一些具体步骤的实现延迟到子类中。这样&#xff0c;子类可以不改变算法的结构即可重新定义算法的某些特定步骤。 二、Ja…...

Arduino 第十六章:pir红外人体传感器练习

Arduino 第十六章&#xff1a;PIR 传感器练习 一、引言 在 Arduino 的众多有趣项目中&#xff0c;传感器的应用是非常重要的一部分。今天我们要学习的主角是 PIR&#xff08;被动红外&#xff09;传感器。PIR 传感器能够检测人体发出的红外线&#xff0c;常用于安防系统、自动…...

C++中间件DDS介绍

C DDS 库简介 DDS&#xff08;Data Distribution Service&#xff09; 是一种用于实时分布式系统通信的中间件标准&#xff0c;由 OMG&#xff08;Object Management Group&#xff09; 提出。它是一种发布/订阅&#xff08;Publish/Subscribe&#xff09;模式的数据通信框架&…...