为什么需要threadlocalLeakPerventionListener
当context reload的时候,如果正在执行的worker线程引用了threadlocal中的变量,会造成整个webclassloader回收不了造成内存泄露,具体请移步tomcat的wiki http://wiki.apache.org/tomcat/MemoryLeakProtection,wiki上比我说得明白。那具体方案也很明确,当context reload的时候,renew线程中的所有的线程,呵呵这活儿得交给listener来做了,所以就有了ThreadLocalLeakPreventionListener,那如何使线程停下来呢,stop这是一个不靠谱的方法,在api已将该方法废弃,幸亏我们还有异常,线程池中的线程遇到异常就会自杀。说多都是废话,还是代码实际
private void stopIdleThreads(Context context) {
if (serverStopping) return;
if (context instanceof StandardContext &&
!((StandardContext) context).getRenewThreadsWhenStoppingContext()) {
log.debug("Not renewing threads when the context is stopping, "
+ "it is configured not to do it.");
return;
}
Engine engine = (Engine) context.getParent().getParent();
Service service = engine.getService();
Connector[] connectors = service.findConnectors();
if (connectors != null) {
for (Connector connector : connectors) {
//获取该context中的所有connector,并获取thread pool
ProtocolHandler handler = connector.getProtocolHandler();
Executor executor = null;
if (handler != null) {
executor = handler.getExecutor();
}
if (executor instanceof ThreadPoolExecutor) {
ThreadPoolExecutor threadPoolExecutor =
(ThreadPoolExecutor) executor;
threadPoolExecutor.contextStopping();
} else if (executor instanceof StandardThreadExecutor) {
StandardThreadExecutor stdThreadExecutor =
(StandardThreadExecutor) executor;
stdThreadExecutor.contextStopping();
}
}
}
}
public void contextStopping() {
//这个时间很关键,当worker线程执行完毕,会根据这个时间判断是否自杀
this.lastContextStoppedTime.set(System.currentTimeMillis());
// save the current pool parameters to restore them later
int savedCorePoolSize = this.getCorePoolSize();
TaskQueue taskQueue =
getQueue() instanceof TaskQueue ? (TaskQueue) getQueue() : null;
if (taskQueue != null) {
// note by slaurent : quite oddly threadPoolExecutor.setCorePoolSize
// checks that queue.remainingCapacity()==0. I did not understand
// why, but to get the intended effect of waking up idle threads, I
// temporarily fake this condition.
taskQueue.setForcedRemainingCapacity(Integer.valueOf(0));
}
// setCorePoolSize(0) wakes idle threads
this.setCorePoolSize(0);
// wait a little so that idle threads wake and poll the queue again,
// this time always with a timeout (queue.poll() instead of
// queue.take())
// even if we did not wait enough, TaskQueue.take() takes care of timing
// out, so that we are sure that all threads of the pool are renewed in
// a limited time, something like
// (threadKeepAlive + longest request time)
try {
Thread.sleep(200L);
} catch (InterruptedException e) {
// yes, ignore
}
if (taskQueue != null) {
// ok, restore the state of the queue and pool
taskQueue.setForcedRemainingCapacity(null);
}
this.setCorePoolSize(savedCorePoolSize);
}
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的整个过程,如有想法,敬请拍砖
分享到:
相关推荐
通过深入理解Tomcat中JNDI的实现原理,尤其是`ContextBinding`机制,我们可以更高效地管理和使用资源,同时增强应用的安全性和可维护性。尽管初看起来JNDI的代码可能显得冗长复杂,但这是为了提供灵活性、安全性和可...
为了更好地理解Tomcat的工作原理,我们可以通过一个简单的Web服务器和servlet容器的实现来深入探讨。例如,创建一个基本的HttpServer类,该类监听特定端口上的连接,并使用Socket类来读取和写入数据。此外,通过实现...
这对于学习Java Web开发和理解Tomcat的工作原理非常有帮助。在实际的开发过程中,大型的Tomcat服务器会包含更多的功能,如多线程处理请求、连接池管理、会话管理、安全管理等,但这个迷你版为我们提供了一个很好的...
**Tomcat服务器工作原理** Tomcat是一款开源的Java Servlet容器,它是Apache软件基金会下的Jakarta项目的核心组件,主要用于部署和运行Java Web应用程序。Tomcat以其轻量级、高效和易于管理的特性,成为了许多...
【标题】:“浅谈Tomcat一些细节配置” Tomcat,作为Apache软件基金会的开源项目,是Java Servlet和JavaServer Pages(JSP)的容器,也是Java EE Web应用程序的标准实现。在实际开发和部署中,对Tomcat进行适当的...
《Tomcat深入剖析》这本书是理解Apache Tomcat服务器工作原理的宝贵资料,它由美国作者撰写并被翻译成中文,适合各个层次的开发者阅读。通过深入学习,读者能够对Tomcat的内部机制有全面而深入的理解,从而更好地...
Tomcat是Apache软件基金会的Java Servlet容器,它实现了Java EE中的Web应用服务器规范。深入理解Tomcat的内部原理有助于我们更好地管理和优化Web应用程序的性能。以下是对Tomcat主要组成部分的详细解析: 1. Server...
【标题】:浅谈Tomcat配置与数据库连接池配置 【描述】:本文将深入探讨如何配置Apache Tomcat服务器以及如何设置数据库连接池,确保服务器高效稳定运行。 **1. 修改Tomcat端口** 在某些场景下,如需运行多台...
**模拟Tomcat工作原理** Tomcat是一款开源的Java Servlet容器,它是Apache软件基金会下的Jakarta项目的一部分,主要用于运行Java Web应用程序。在这个模拟过程中,我们将深入理解Tomcat如何处理HTTP请求,以及它在...
Tomcat工作原理深入解析 Tomcat作为一款广泛应用的开源Java Servlet容器,它的内部架构和工作流程对于理解Web应用的运行至关重要。本文将深入探讨Tomcat的主要组成部分,包括Server、Service、Connector、Engine、...
《Tomcat工作原理详解》 Tomcat作为一款广泛使用的开源Java应用服务器,其工作原理是许多开发者想要深入了解的关键。本文将从多个层面深入探讨Tomcat的运作机制,旨在帮助读者全面理解其设计思想和核心功能。 一、...
**Tomcat启动原理解析** Tomcat作为一款广泛使用的开源Java应用服务器,其启动过程涉及了众多关键步骤和组件的协同工作。理解Tomcat的启动原理对于开发者来说至关重要,不仅有助于提升性能优化的能力,还能在遇到...
3-3Tomcat响应流程原理和源码解析.mp4
### Eclipse调用Tomcat服务的原理及虚拟部署目录详解 #### 概述 Eclipse作为一款流行的集成开发环境(IDE),被广泛应用于Java Web项目的开发过程中。而在开发Java Web应用时,通常会与Tomcat服务器配合使用。了解...
### Tomcat工作原理详解 #### 一、概览 Tomcat是Apache软件基金会下的Jakarta项目中的一个开源的Web服务器和Servlet容器。它主要用来运行Java Web应用,并且支持Servlet和JSP技术。Tomcat的核心架构包括多个组件,...
本示例聚焦于如何利用Struts2框架和Tomcat服务器来实现这一功能。以下是对这个主题的详细阐述: 首先,我们需要理解Struts2和Tomcat的基础知识。Struts2是一个基于MVC(Model-View-Controller)设计模式的Java Web...
《Tomcat架构原理》深入解析 一、Tomcat架构概览 Apache Tomcat是一个开源的Servlet容器,由Apache软件基金会的Jakarta项目提供。它主要实现了Servlet和JavaServer Pages(JSP)技术规范,同时也提供了HTTP服务器...
Apache Tomcat,作为Java社区中一个非常重要的开源容器,实现了Java Servlet和JavaServer Pages(JSP)技术规范。它由多个组件构成,主要用于运行Java Servlet和JSP代码,向客户端提供Web应用服务。为了理解Tomcat的...