Java Thread线程上下文类加载器

培训教学 潘老师 6个月前 (11-08) 131 ℃ (0) 扫码查看

本文重点讲解Java Thread线程上下文类加载器,在讲解线程上下文类加载器之前,我们需要了解下什么是线程上下文类加载器。

在Java多线程中,经常会出现跨类加载器的情况,例如Web容器中的应用程序的类加载器和Java线程在使用的类加载器可以是不同的实例。

而在Java中,不同的类加载器对于同一个类的加载得到的Class对象实例是不同的,这样就会导致在不同的类加载器中创建的对象实例无法相互转换,从而引发一系列问题。为此,Java中引入了线程上下文类加载器的概念。

1、什么是线程上下文类加载器

线程上下文类加载器(context class loader)是从 JDK 1.2 开始引入的。类 java.lang.Thread中的方法 getContextClassLoader()和 setContextClassLoader(ClassLoader cl)用来获取和设置线程的上下文类加载器。

如果没有通过 setContextClassLoader(ClassLoader cl)方法进行设置的话,线程将继承其父线程的上下文类加载器,如果在应用程序全局范围内都没设置,那么这个类加载器默认是app类加载器。

Java应用运行时的初始线程的上下文类加载器是系统类加载器。在线程中运行的代码可以通过该类加载器来加载类与资源。

2、线程上下文类加载器源码

@CallerSensitive
public ClassLoader getContextClassLoader() {
 
    if (contextClassLoader == null)
        return null;
    SecurityManager sm = System.getSecurityManager();
    if (sm != null) {
 
        ClassLoader.checkClassLoaderPermission(contextClassLoader,
                                               Reflection.getCallerClass());
    }
    return contextClassLoader;
}
public void setContextClassLoader(ClassLoader cl) {
 
    SecurityManager sm = System.getSecurityManager();
    if (sm != null) {
 
        sm.checkPermission(new RuntimePermission("setContextClassLoader"));
    }
    contextClassLoader = cl;
}

public ClassLoader getContextClassLoader()获取线程上下文的类加载器,简单来说就是这个线程是由哪个类加器加载的,如果是在没有修改线程上下文类加载器的情况下,则保持与父线程同样的类加载器。

public void setContextClassLoader(ClassLoader cl)设置该线程的类加载器,这个方法可以打破JAVA类加载器的父委托机制,有时候该方法也被称为JAVA类加载器的后门。

3、重要性

它可以打破双亲委托机制,父ClassLoader可以使用当前线程的Thread.currentThread().getContextClassLoader()所指定的classLoader来加载类,这就可以改变父ClassLoader不能使用子ClassLoader或是其他没有直接父子关系的ClassLoader加载的类的情况,即改变了双亲委托模型。

4、使用场景

对于SPI来说,有些接口是Java核心库所提供的,而Java核心库是由启动类加载器加载的,而这些接口的实现却是来自于不同jar包(厂商提供),Java的启动类加载是不会加载其他来源的jar包,这样传统的双亲委托模型就无法满足SPI的要求。而通过给当前线程设置上下文类加载器,就可以由设置的上线文类加载器来实现与借口哦实现类的加载。

5、总结

以上就是Java Thread线程上下文类加载器的内容,大家了解下即可。


版权声明:本站文章,如无说明,均为本站原创,转载请注明文章来源。如有侵权,请联系博主删除。
本文链接:https://www.panziye.com/teach/10752.html
喜欢 (0)
请潘老师喝杯Coffee吧!】
分享 (0)
用户头像
发表我的评论
取消评论
表情 贴图 签到 代码

Hi,您需要填写昵称和邮箱!

  • 昵称【必填】
  • 邮箱【必填】
  • 网址【可选】