【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),分别用来 ...
随机推荐
- JVM命令jps
jps是JVM的一个常用命令,类似linux中的ps命令.jps是查看java进程信息的命令:ps是查看linux系统中进程的命令 格式 jps [ options ] [ host ...
- CodeForces 839B - Game of the Rows | Codeforces Round #428 (Div. 2)
血崩- - /* CodeForces 839B - Game of the Rows [ 贪心,分类讨论] | Codeforces Round #428 (Div. 2) 注意 2 7 2 2 2 ...
- web+下载文件夹
文件下载的实质就是文件拷贝,将文件从服务器端拷贝到浏览器端,所以文件下载需要IO技术将服务器端的文件读取到,然后写到response缓冲区中,然后再下载到个人客户端. "> <m ...
- learning armbian steps(8) ----- armbian 源码分析(三)
在lib/main.sh当中 ) == main.sh ]]; then echo "Please use compile.sh to start the build process&quo ...
- Java进阶知识10 Hibernate一对多_多对一双向关联(Annotation+XML实现)
本文知识点(目录): 1.Annotation 注解版(只是测试建表) 2.XML版 的实现(只是测试建表) 3.附录(Annotation 注解版CRUD操作)[注解版有个问题:插入值时 ...
- 修改Ubuntu国内镜像
打开软件和更新:如下图 选择一个自己喜欢的镜像. 然后执行 sudo apt-get update 更新源. 结束 1.原文件备份 sudo cp /etc/apt/sources.list ...
- vue中用watch监听当前路由
之前做项目时,特别是后台项目,左边都有侧边栏,我们需要做到点击某个侧边栏的项让这个项高亮,之前采用的是给每个项绑定一个值,点击某个项时,就将这个值付给一个变量,在每一项上判断这个变量是否与每项上的值相 ...
- Jquery 2.0+版本不支持IE8,如何解决?
用了JQuery2.0+以后,在IE8下会报错,下面是我的方法. 先看代码: <!--[if !IE]> --> <script src="/Scrip ...
- mybatis 多级级联(多级嵌套)
注:笔者这里的嵌套可以用词有点欠缺,忘见谅 需求:用一个查询接口查出其结果集,这里就用伪代码标识要返回前端的类与类之间的关系. class 顶层{ String otherValue; LinkedL ...
- [51nod1789] 跑得比谁都快
题面 题解 设\(f[i]\)为根节点到\(i\)的最小耗时 设\(S\)为\(i\)的祖先集合, 可以得到 \[ f[i] = min(f[j] + (i - j)^p),j \in S \] 对于 ...