浅谈tomcat的ThreadLocalLeakPreventionListener实现原理
为什么需要threadlocalLeakPerventionListener
??? 当context reload的时候,如果正在执行的worker线程引用了threadlocal中的变量,会造成整个webclassloader回收不了造成内存泄露,具体请移步tomcat的wiki http://wiki.apache.org/tomcat/MemoryLeakProtection,wiki上比我说得明白。那具体方案也很明确,当context reload的时候,renew线程中的所有的线程,呵呵这活儿得交给listener来做了,所以就有了ThreadLocalLeakPreventionListener,那如何使线程停下来呢,stop这是一个不靠谱的方法,在api已将该方法废弃,幸亏我们还有异常,线程池中的线程遇到异常就会自杀。说多都是废话,还是代码实际
?
protected void stopCurrentThreadIfNeeded() { if (currentThreadShouldBeStopped()) { long lastTime = lastTimeThreadKilledItself.longValue(); 判断这个线程是否需要自杀,就是根据context stop的时间+delay是否小于当前,如小于抛出异常自杀 if (lastTime + threadRenewalDelay < System.currentTimeMillis()) { if (lastTimeThreadKilledItself.compareAndSet(lastTime, System.currentTimeMillis() + 1)) { // OK, it's really time to dispose of this thread final String msg = sm.getString( "threadPoolExecutor.threadStoppedToAvoidPotentialLeak", Thread.currentThread().getName()); Thread.currentThread().setUncaughtExceptionHandler( new UncaughtExceptionHandler() { @Override public void uncaughtException(Thread t, Throwable e) { // yes, swallow the exception log.debug(msg); } }); throw new RuntimeException(msg); } } } }?
? 粗略地marker一下thread renew的整个过程,如有想法,敬请拍砖?