关于使用ContextClassLoader遇到的问题
关于使用ContextClassLoader遇到的问题
对ContextClassLoader有一些疑惑:
- 父线程加载的Class,子线程是否可以使用该Class? 答:可以
- 子线程加载的Class,父线程是否可以使用该Class? 答:不可以
- 如果一个线程加载的Class,其他线程是否可以使用该Class ? 答:不可以
- 怎么使用ContextClassLoader才是正确姿势呢? 答:取出->更改->还原(finally语句块)。
关于上述4点疑问,做了以下测试:
父线程加载的Class,子线程是否可以使用该Class?
/** * Thread.currentThread().setContextClassLoader * 如果父线程加载了某个class, 那么子线程也可以使用该class */ public class Test2 { public static void main(String[] args) throws InterruptedException { ClassLoader ccl = Thread.currentThread().getContextClassLoader(); MyClassLoader classLoader = new MyClassLoader(); classLoader.setClassFile(new File("D:\\UserService3Impl.class")); Thread.currentThread().setContextClassLoader(classLoader); try { classLoader.loadClass("com.sample.mybatis.service.impl.UserService3Impl"); } catch (Exception e) { e.printStackTrace(); } Thread thread = new Thread(() -> { try { Class<?> userClass = Thread.currentThread().getContextClassLoader().loadClass("com.sample.mybatis.service.impl.UserService3Impl"); System.out.println(userClass); UserService3 userObj = (UserService3)userClass.newInstance(); System.out.println(Thread.currentThread().getName() + " ==> " + userObj.getUserNo()); } catch (Exception e) { e.printStackTrace(); } }); thread.start(); } }
运行结果:
结论:父线程加载的Class,子线程是可以使用该Class
子线程加载的Class,父线程是否可以使用该Class?
/** * Thread.currentThread().setContextClassLoader * 如果子线程加载了某个class, 那么父线程不能共享到该class */ public class Test4 { public static void main(String[] args) throws Exception { Thread thread = new Thread(() -> { try { MyClassLoader classLoader = new MyClassLoader(); classLoader.setClassFile(new File("D:\\UserService3Impl.class")); Thread.currentThread().setContextClassLoader(classLoader); try { classLoader.loadClass("com.sample.mybatis.service.impl.UserService3Impl"); } catch (Exception e) { e.printStackTrace(); } } catch (Exception e) { e.printStackTrace(); } }); thread.start(); thread.join(); Class<?> userClass = Thread.currentThread().getContextClassLoader().loadClass("com.sample.mybatis.service.impl.UserService3Impl"); System.out.println(userClass); UserService3 userObj = (UserService3) userClass.newInstance(); System.out.println(Thread.currentThread().getName() + " ==> " + userObj.getUserNo()); } }
运行结果:
结论:子线程加载的Class,父线程是不可以使用该Class
如果一个线程加载的Class,其他线程是否可以使用该Class?
测试代码:
/** * 如果两个线程不是父子线程, 线程之间不会共享加载过的class */ public class Test3 { public static void main(String[] args) throws InterruptedException { Thread thread = new Thread(() -> { MyClassLoader classLoader = new MyClassLoader(); classLoader.setClassFile(new File("D:\\UserService3Impl.class")); Thread.currentThread().setContextClassLoader(classLoader); Class<?> userClass = null; try { userClass = classLoader.loadClass("com.sample.mybatis.service.impl.UserService3Impl"); System.out.println(userClass); UserService3 userObj = (UserService3) userClass.newInstance(); System.out.println(Thread.currentThread().getName() + " ==> " + userObj.getUserNo()); } catch (Exception e) { e.printStackTrace(); } }); thread.start(); thread.join(); Thread thread2 = new Thread(() -> { try { Class<?> userClass = Thread.currentThread().getContextClassLoader().loadClass("com.sample.mybatis.service.impl.UserService3Impl"); System.out.println(userClass); UserService3 userObj = (UserService3) userClass.newInstance(); System.out.println(Thread.currentThread().getName() + " ==> " + userObj.getUserNo()); } catch (Exception e) { e.printStackTrace(); } }); thread2.start(); } }
运行结果:
总结:如果一个线程加载的Class,其他线程是不可以使用该Class
怎么使用ContextClassLoader才是正确姿势呢?
ClassLoader ccl = Thread.currentThread().getContextClassLoader(); //取出 try { MyClassLoader classLoader = new MyClassLoader(); classLoader.setClassFile(new File("D:\\UserService3Impl.class")); Thread.currentThread().setContextClassLoader(classLoader); //设置 //其他逻辑。。。 }finally { Thread.currentThread().setContextClassLoader(ccl); //还原 }
到此这篇关于关于使用ContextClassLoader遇到的问题的文章就介绍到这了,更多相关ContextClassLoader使用详解内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
Spring,hibernate,struts经典面试笔试题(含答案)
这篇文章主要介绍了Spring,hibernate,struts经典面试笔试题极其参考含答案,涉及SSH基本概念,原理与使用技巧,需要的朋友可以参考下2016-03-03SpringMVC通过模型视图ModelAndView渲染视图的实现
这篇文章主要介绍了SpringMVC通过模型视图ModelAndView渲染视图的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧2020-12-12SpringBoot整合RabbitMQ实现交换机与队列的绑定
这篇文章将通过几个实例为大家介绍一些SpringBoot中RabbitMQ如何绑定交换机(交换器)与队列,文中的示例代码讲解详细,感兴趣的可以了解一下2022-05-05idea中增强for循环提示unexpected token问题
这篇文章主要介绍了idea中增强for循环提示unexpected token问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教2024-01-01解决idea使用maven编译正常但是运行项目时却提示很多jar包找不到的问题
这篇文章主要介绍了解决idea使用maven编译正常但是运行项目时却提示很多jar包找不到的问题,本文分多种情形给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下2020-07-07
最新评论