WEB开发网
开发学院软件开发Java Classloader和线程 阅读

Classloader和线程

 2012-07-26 19:53:30 来源:WEB开发网   
核心提示: Java中所有的类都是由classloader进行加载的,通常情况下我们不需要显式的去使用类加载器,Classloader和线程,但是对于一个web容器而言,通常拥有多个classloader,这个就是类加载器隔离的关键,我们可以很容易写一小段代码来证实:下面这段代码运行后输出是,我们知道,每个classloade

  Java中所有的类都是由classloader进行加载的。
通常情况下我们不需要显式的去使用类加载器。

但是对于一个web容器而言,通常拥有多个classloader,我们知道,每个classloader所加载的类彼此都是不可见的。比如一个servlet程序,它使用了WEB-INF/lib下面的log4j,而tomcat本身也有一套logj的包。显然对于servlet而言,它是看不到tomcat的log4j,反之亦然。

这一点如何做到?
答案就是线程自身的contextClassLoader。我们知道java代码总是在某个线程中执行的,这个线程所需要的类,则是由它自己的contextClassLoader所加载;当一个线程开启了一个子线程,则子线程会隐式的继承父线程的classloader。这个就是类加载器隔离的关键。

我们可以很容易写一小段代码来证实:
下面这段代码运行后输出是,

main_cl:[email protected]
MainProc:[email protected]
SubProc:[email protected]

证明了上面这个结论。

class MainProc implements Runnable { 
      @Override 
      public void run() { 
             out.println( "MainProc:" + Thread.currentThread().getContextClassLoader()); 
             new Thread( new SubProc()).start(); 
      } 
} 
 
class SubProc implements Runnable { 
      @Override 
      public void run() { 
             out.println( "SubProc:" + Thread.currentThread().getContextClassLoader()); 
      } 
} 
 
class MyClassLoader extends URLClassLoader { 
      public MyClassLoader(URL[] urls) { 
             super(urls); 
      } 
} 
 
public class AsciiUtil { 
       
      public static void main(String[] args) throws Exception { 
             out.println( "main_cl:" + Thread.currentThread().getContextClassLoader()); 
             
            URL url = new URL( "file:///c:/Program Files/Java/jre6/lib" ); 
            MyClassLoader mcl = new MyClassLoader( new URL[]{url}); 
            Thread. currentThread().setContextClassLoader(mcl); 
             
             new Thread( new MainProc()).start(); 
      } 
 
} 

Tags:Classloader 线程

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接