【JVM学习笔记】线程上下文类加载器
有许多地方能够看到线程上下文类加载的设置,比如在sun.misc.Launcher类的构造方法中,能够看到如下代码

先写一个例子建立感性认识
public class Test {
public static void main(String[] args) {
System.out.println(Thread.currentThread().getContextClassLoader());
System.out.println(Thread.class.getClassLoader());
}
}
输出
sun.misc.Launcher$AppClassLoader@18b4aac2
null
这是因为Thread类位于rt.jar包,而当前线程的上下文加载器,也就是加载了main函数所在类的加载器,其实就是系统类加载器
当前类加载器(Current ClassLoader)的概念
每个类都会使用自己的类加载器(即加载自身的类加载器)去加载所依赖的其他类。比如说ClassX引用了ClassY,那么ClassX的类加载器就会去加载ClassY,前提是ClassY尚未被加载。
线程上下文类加载器(Context ClassLoader)
线程上下文类加载器是从JDK1.2开始引入的,类Thread中的getContextClassLoader()于setContextClassLoader(ClassLoader cl)分别用来获取和设置上下文类加载器。
如果没有通过setContextClassLoader(ClassLoader cl)进行设置的话,线程将继承其父线程的上下文类加载器。
Java应用运行时的初始线程的上下文加载器是系统类加载器。线程中运行的代码,可以通过该类加载器来加载类与资源。
线程上下文类加载器的重要性
以JDBC为例,Connection是JDBC的标准接口,该接口位于rt.jar包里,而厂商提供的具体实现则是在厂商提供的jar包里。所以接口部分是由启动类加载器加载的,而实现是由系统类加载器加载的,这样就导致一个问题:根据双亲委托机制,父加载器加载的类无法看到子加载器加载的类,如果rt包中的某些类想要引用第三方厂商jar包里的实现类,就无法引用了。这是双亲委托模型在此类似情况下会出现的问题。这种由第三方厂商提供实现的方式,称为SPI(Service Provider Interface)
使用线程上下文类加载器,父ClassLoader可以使用当前线程Thread.currentThread().getContextClassLoader()所指定的classloader加载的类。这就改变了父ClassLoader不能使用子ClassLoader,或是其他没有直接父子关系的ClassLoader加载的类的情况,即改变了双亲委托模型。
更具体地来说,在main函数中使用ServiceLoader.load(Driver.class) 加载MySql驱动,由于ServiceLoader类在rt.jar包里,如果没有上下文类加载器这种机制,ServiceLoader类内部只会通过启动类加载器去尝试加载驱动,而驱动在第三方jar包里,因此它无法加载,导致失败。
线程上下文类加载器就是打破双亲委托模型的一种方式
【JVM学习笔记】线程上下文类加载器的更多相关文章
- 【JVM学习笔记】系统类加载器
可以通过“java.system.class.loader"属性指定系统类加载器 默认情况下,该属性值为空: public class Test { public static void m ...
- 【JVM学习笔记】扩展类加载器
扩展类加载器独有的特点,代码如下 public class Sample { } public class Test { static { System.out.println("Test ...
- JVM 线程上下文类加载器
当前类加载器(Current ClassLoader) 每个类都会使用自己的类加载器(即加载自身的类加载器)来去加载其他类(指所依赖的类) 如果ClassX引用了ClassY,那么ClassX的类加载 ...
- 7. 通过JDBC源码来分析线程上下文类加载器以及SPI的使用
目录 1. 什么是全盘负责委托机制 2. 为什么需要有线程上下文类加载器 2.1 使用JDBC的例子,分析为什么双亲委托机制不能实现要求 2.2 线程上下文类加载器的作用 3. 线程上下文类加载器的使 ...
- 通过JDBC驱动加载深刻理解线程上下文类加载器机制
关于线程上下文类加载器已经在之前学得比较透了,作为一个收尾,这里用平常J2EE开发时JDBC连接Mysql数据库常见的一段代码通过分析它的底层进一步加深对线程上下文类加载器的理解,所以先来将连接应用代 ...
- 线程上下文类加载器ContextClassLoader内存泄漏隐患
前提 今天(2020-01-18)在编写Netty相关代码的时候,从Netty源码中的ThreadDeathWatcher和GlobalEventExecutor追溯到两个和线程上下文类加载器Cont ...
- 深入理解Java类加载器(二):线程上下文类加载器
摘要: 博文<深入理解Java类加载器(一):Java类加载原理解析>提到的类加载器的双亲委派模型并不是一个强制性的约束模型,而是Java设计者推荐给开发者的类加载器的实现方式.在Java ...
- 【Java虚拟机11】线程上下文类加载器
前言 目前学习到的类加载的知识,都是基于[双亲委托机制]的.那么JDK难道就没有提供一种打破双亲委托机制的类加载机制吗? 答案是否定的. JDK为我们提供了一种打破双亲委托模型的机制:线程上下文类加载 ...
- 线程上下文类加载器(Context ClassLoader)
1.线程上下文类加载器是从jdk1.2开始引入的,类Thread中的getContextClassLoader()与setContextClassLoader(ClassLoader c1),分别用来 ...
随机推荐
- Jenkins构建从github上克隆时,报Host key verification failed.
首先在本地通过CMD执行git clone xxxxx时,可以成功的通过免密(SSH_KEY)克隆下来代码,但是通过Jenkins克隆时,就报如下信息: Cloning into 'GitHub'.. ...
- 最简单之安装azkaban
一,拉取源码构建 git clone https://github.com/azkaban/azkaban.git cd azkaban; ./gradlew build installDist 二, ...
- HDU - 5033 Building (单调栈+倍增)
题意:有一排建筑,每座建筑有一定的高度,宽度可以忽略,求在某点的平地上能看到天空的最大角度. 网上的做法基本都是离线的...其实这道题是可以在线做的. 对于向右能看到的最大角度,从右往左倍增维护每个时 ...
- MySQL 下载与安装使用教程
MySQL 官网地址:https://www.mysql.com/ 等待下载完成 双击运行 如果有需要 我们可以新增一个用户出来 点击 Add User,不需要的话 直接 点击 next 默认的MyS ...
- 方程的解——枚举&&水题
题目 链接 给出方程组:$$\displaystyle \left\{\begin{aligned}11x + 13y + 17z = 2471 \\13x + 17y + 11z = 2739\en ...
- [Sping Boot] Build a REST CRUD API with Hibernate
pom.xml: <dependencies> <dependency> <groupId>org.springframework.boot</groupId ...
- http协议。会话控制cookie、session
http协议是无状态的协议.每次访问页面的http协议都是独立的,正是因为http协议是无状态的,所以导致访问一个页面后再去访问另一个页面的时候,一些数据会消失,比如:用户的登录信息就会消失.那么怎么 ...
- php实现浏览器大文件分片上传
PHP用超级全局变量数组$_FILES来记录文件上传相关信息的. 1.file_uploads=on/off 是否允许通过http方式上传文件 2.max_execution_time=30 允许脚本 ...
- struts2 404错误
action类必须放在xxxx.xxx.xxx.xxx.action 包下才可以.
- 积性函数,线性筛入门 HDU - 2879
HDU - 2879HeHe 题意:He[N]为[0,N−1]范围内有多少个数满足式子x2≡x (mod N),求HeHe[N]=He[1]×……×He[N] 我是通过打表发现的he[x]=2k,k为 ...