Java Thread.setContextClassLoader能否设置与getCCL返回的不同的类加载器?
背景: 最近,我实现了一段代码,该代码将为特定操作设置适当的类加载器,并在操作完成后最终恢复原始的类加载器 例如:Java Thread.setContextClassLoader能否设置与getCCL返回的不同的类加载器?,java,classloader,contextclassloader,Java,Classloader,Contextclassloader,背景: 最近,我实现了一段代码,该代码将为特定操作设置适当的类加载器,并在操作完成后最终恢复原始的类加载器 例如: ClassLoader originalCL = Thread.currentThread().getContextClassLoader(); try { Thread.currentThread().setContextClassLoader(specialCL); // do operation here that requires 'specialCL' }
ClassLoader originalCL = Thread.currentThread().getContextClassLoader();
try {
Thread.currentThread().setContextClassLoader(specialCL);
// do operation here that requires 'specialCL'
} finally {
Thread.currentThread().setContextClassLoader(originalCL);
}
// start out with System CL
ClassLoader original = getContextClassLoader(); // returns null
Thread.currentThread().setContextClassLoader(otherCL);
Thread.currentThread().setContextClassLoader(original); // i.e. set to null
// setCCL() tries to set System CL... fails
// setCCL() tries to set Bootstrap CL... succeeds
根据getContextClassLoader()
doc,返回null可能意味着两件事。1) 系统CL或2)如果获取系统CL失败,则引导CL
返回:此线程的上下文类加载器,或null表示系统类加载器(否则为引导类加载器)
根据setContextClassLoader(Classloader cl)
doc,如果提供了空cl,则1)系统cl或2)如果设置系统cl失败,则引导cl
cl-此线程的上下文类加载器,或null,表示系统类加载器(否则,表示引导类加载器)
问题: 使用上面的try-finally-restore编程模型,我是否可能在线程上得到一个与我最初使用的不同的类加载器 例如:
ClassLoader originalCL = Thread.currentThread().getContextClassLoader();
try {
Thread.currentThread().setContextClassLoader(specialCL);
// do operation here that requires 'specialCL'
} finally {
Thread.currentThread().setContextClassLoader(originalCL);
}
// start out with System CL
ClassLoader original = getContextClassLoader(); // returns null
Thread.currentThread().setContextClassLoader(otherCL);
Thread.currentThread().setContextClassLoader(original); // i.e. set to null
// setCCL() tries to set System CL... fails
// setCCL() tries to set Bootstrap CL... succeeds
当我们从引导CL开始时,当我们尝试使用
setContextClassLoader(null)
恢复系统CL时,情况也可能相反。这两种情况都可能吗?否,当您将上下文类加载器设置为null
时,只需将其设置为null
。因此,它将继续使用它最初使用的任何类加载器。对最初使用的类加载器的引用存储在哪里?在我的示例中,我将类加载器设置为其他类型,然后尝试恢复it@aguibert在OpenJDK实现中,Thread
类只是有一个名为的字段。我不清楚的部分是故障转移机制是如何工作的,什么时候起作用?显然,将字段设置为null永远不会失败,那么为什么javadoc描述了它的行为呢?如果有人能描述为什么提到故障转移,我会认为这是足够的。answer@aguibert我想你可能误解了“失败”这个成语。它只是意味着“如果那不可用”,而不是任何实际的失败。