1.两种原因
第一种,也是最常见的一种,就是多个线程使用ThreadLocal 第二种,类加载器不同造成取不到值,本质原因就是不同类加载器造成多个ThreadLocal对象
public class StaticClassLoaderTest {
protected static final ThreadLocal< Object> local = new ThreadLocal < Object> ( ) ;
private Test3 test3;
public StaticClassLoaderTest ( ) {
try {
test3 = ( Test3) Class. forName ( "gittest.Test3" , true , new cusLoader ( ) ) . newInstance ( ) ;
}
catch ( Exception e) {
e. printStackTrace ( ) ;
}
}
public Test3 getTest3 ( ) {
return test3;
}
public static void main ( String[ ] args) {
try {
StaticClassLoaderTest. local. set ( new Object ( ) ) ;
new StaticClassLoaderTest ( ) . getTest3 ( ) ;
}
catch ( Exception e) {
e. printStackTrace ( ) ;
}
}
public static class cusLoader extends ClassLoader {
@Override
protected Class< ? > loadClass ( String name, boolean resolve) throws ClassNotFoundException {
if ( name. contains ( "StaticClassLoaderTest" ) ) {
InputStream is = Thread. currentThread ( ) . getContextClassLoader ( )
. getResourceAsStream ( name. replace ( "." , "/" ) + ".class" ) ;
ByteArrayOutputStream output = new ByteArrayOutputStream ( ) ;
try {
IOUtils. copy ( is, output) ;
return defineClass ( output. toByteArray ( ) , 0 , output. toByteArray ( ) . length) ;
}
catch ( IOException e) {
e. printStackTrace ( ) ;
}
}
return super . loadClass ( name, resolve) ;
}
}
}
public class Test3 {
public void test ( ) {
System. out. println ( StaticClassLoaderTest. local. get ( ) ) ;
}
}
2.总结
2个类加器加载的对象引用了相同的静态变量ThreadLocal,实际上ThreadLocal并不是同一个值,所以即使在一个线程中也获取不到期望的值。 像依赖注入,如果你自己创建了一个对象,然后用手动注入了一个容器创建的依赖,假设这个依赖是自定义类加器创建的,可能会造成这种情况。