Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/355.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/webpack/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Thread.setContextClassLoader能否设置与getCCL返回的不同的类加载器?_Java_Classloader_Contextclassloader - Fatal编程技术网

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我想你可能误解了“失败”这个成语。它只是意味着“如果那不可用”,而不是任何实际的失败。