我们知道静态变量是ClassLoader级别的,如果Web应用程序停止,这些静态变量也会从JVM中清除。但是线程则是JVM级别的,如果你在Web 应用中启动一个线程,这个线程的生命周期并不会和Web应用程序保持同步。也就是说,即使你停止了Web应用,这个线程依旧是活跃的。正是因为这个很隐晦 的问题,所以很多有经验的开发者不太赞成在Web应用中私自启动线程。
如果我们手工使用JDK Timer(Quartz的Scheduler),在Web容器启动时启动Timer,当Web容器关闭时,除非你手工关闭这个Timer,否则Timer中的任务还会继续运行!
下面通过一个小例子来演示这个“诡异”的现象,我们通过ServletContextListener在Web容器启动时创建一个Timer并周期性地运行一个任务:
//代码清单StartCycleRunTask:容器监听器 package com.baobaotao.web; import java.util.Date; import java.util.Timer; import java.util.TimerTask; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; public class StartCycleRunTask implements ServletContextListener ...{ private Timer timer; public void contextDestroyed(ServletContextEvent arg0) ...{ // ②该方法在Web容器关闭时执行 System.out.println("Web应用程序启动关闭..."); } public void contextInitialized(ServletContextEvent arg0) ...{ //②在Web容器启动时自动执行该方法 System.out.println("Web应用程序启动..."); timer = new Timer();//②-1:创建一个Timer,Timer内部自动创建一个背景线程 TimerTask task = new SimpleTimerTask(); timer.schedule(task, 1000L, 5000L); //②-2:注册一个5秒钟运行一次的任务 } } class SimpleTimerTask extends TimerTask ...{//③任务 private int count; public void run() ...{ System.out.println((++count)+"execute task..."+(new Date())); } }
在web.xml中声明这个Web容器监听器:<?xml version="1.0" encoding="UTF-8"?>
<web-app>
…
<listener>
<listener-class>com.baobaotao.web.StartCycleRunTask</listener-class>
</listener>
</web-app>
在Tomcat中部署这个Web应用并启动后,你将看到任务每隔5秒钟执行一次。
运行一段时间后,登录Tomcat管理后台,将对应的Web应用(chapter13)关闭。
转到Tomcat控制台,你将看到虽然Web应用已经关闭,但Timer任务还在我行我素地执行如故——舞台已经拆除,戏子继续表演:
我们可以通过改变清单StartCycleRunTask的代码,在contextDestroyed(ServletContextEvent arg0)中添加timer.cancel()代码,在Web容器关闭后手工停止Timer来结束任务。
Spring为JDK Timer和Quartz Scheduler所提供的TimerFactoryBean和SchedulerFactoryBean能够和Spring容器的生命周期关联,在 Spring容器启动时启动调度器,而在Spring容器关闭时,停止调度器。所以在Spring中通过这两个FactoryBean配置调度器,再从 Spring IoC中获取调度器引用进行任务调度将不会出现这种Web容器关闭而任务依然运行的问题。而如果你在程序中直接使用Timer或Scheduler,如不 进行额外的处理,将会出现这一问题。
转自:http://coach.iteye.com/blog/854996
相关推荐
Apache Tomcat是一个开源的Servlet容器,它实现了Java Servlet和JavaServer Pages(JSP)规范,是部署Java Web应用程序的常用工具。 首先,我们来看`shutdown.bat`文件。这个文件是Windows操作系统下的批处理脚本,...
在Web应用程序中集成Quartz,可以实现后台任务的自动化处理,比如数据同步、报表生成、邮件发送等。这篇博客“quartz单机和WEB应用”可能是探讨如何在单机环境下配置和使用Quartz,以及如何在Web应用中集成Quartz来...
Java应用程序,特别是Web应用,经常会在启动时开启线程、监听端口等服务。当应用被卸载时,如果没有在对应的`ServletContextListener`的`contextDestroyed`方法或Servlet的`destroy`方法中停止这些服务,就会导致...
- 对于使用了外部库的应用程序,确保所有打开的资源都能正确关闭。 - 定期进行代码审查,查找可能导致内存泄漏的代码段,比如循环引用等。 4. **监控与诊断**: - 使用工具如VisualVM、JProfiler等监控Tomcat的...
这个类将在Web应用启动和关闭时分别调用`contextInitialized()`和`contextDestroyed()`方法。 ```java import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; public class ...
C#是一种广泛应用于桌面应用、游戏开发、Web应用和服务器端编程的面向对象的编程语言。在本项目中,"c#多线程端口扫描程序源代码" 提供了一个利用C#实现的网络工具,它能扫描指定目标主机的多个端口,以检测哪些端口...
后台线程则不阻止应用程序关闭,即使有后台线程还在运行。 ### BeginXXX和EndXXX方法 这些方法用于异步编程,BeginXXX启动异步操作,EndXXX用于获取操作的结果。当操作完成后,可以通过EndXXX方法同步地等待结果。 ...
在E语言中,多线程能够帮助开发者在处理大量I/O操作、复杂的计算任务或者需要实时交互的应用场景时,提高程序的效率。通过创建多个线程,每个线程可以独立执行一段代码,而不影响其他线程的运行。 二、E语言中的...
在Java Web应用开发中,错误和异常的处理是不可或缺的一部分,因为它们直接影响到程序的稳定性和用户体验。本文将深入探讨Java Web应用中遇到的一些常见错误和异常问题,并提供相应的处理策略。 1. **Servlet和JSP...
“C#小应用程序”标签暗示这可能是一个轻量级的程序,专为快速启动和简单操作而设计。在C#中,可以利用Windows Forms或WPF(Windows Presentation Foundation)创建这样的应用。Windows Forms更适合快速开发,而WPF...
ASP.NET是一种由微软开发的服务器端Web应用程序框架,主要用于构建动态网站、Web应用程序和服务。在这个“基于ASP.NET的多线程TCP端口扫描程序源码”项目中,开发者利用了ASP.NET的技术特性来实现了一个功能强大的...
VB.NET是Microsoft .NET框架的一部分,提供了一种面向对象的编程环境,允许开发者创建桌面应用程序、Web应用程序和服务。VBEXE是Visual Basic .NET编译后的程序文件形式,通常包含完整的运行时环境,可以在没有安装...
在IT行业中,编程语言C#是一种广泛用于开发桌面应用、Web应用、游戏和移动应用的强大工具。本项目“定时开关程序”是利用C#编写的一个实用程序,它能够按照预设的时间间隔执行启动或关闭指定程序的操作。对于那些...
### JAVA程序设计语言Applet应用程序知识点详解 #### 1. Java程序分类 Java程序主要分为两类:Java Application 和 Java Applet。 - **Java Application**:这类程序是独立运行的Java程序,通常具备`main`方法作为...
**XML Web Services** 是.NET Framework 中的一个重要概念,它允许不同系统之间的应用程序通过网络进行交互和共享数据。通过XML Web Services,不同平台的应用程序可以无缝地协同工作,即使它们使用的编程语言和操作...
在IT领域,C#是一种广泛使用的编程语言,尤其在开发Windows桌面应用、Web应用以及服务端应用程序时。本文将深入探讨如何使用C#构建一个定时操作的控制台应用程序,这在自动化任务执行、数据同步或者定期备份等场景中...
这个方法会结束当前应用程序线程,导致应用程序关闭。在大多数情况下,调用此方法会结束整个应用程序,除非有其他非UI线程仍在运行。 为了在退出程序后立即重新启动,我们可以创建一个新的线程并在退出之前启动它。...
《.NET线程问答 .NET线程全...以上内容涵盖了.NET线程的基础知识,包括创建、使用和管理线程,以及在特定环境如WinForm和Web应用中的实践策略。理解并熟练运用这些知识,能帮助开发者编写出更加高效和健壮的并发程序。
在Linux环境下部署和管理Java Web应用程序时,Apache Tomcat作为一款广泛使用的应用服务器,其操作过程对于系统管理员和开发人员来说至关重要。本文将详细介绍如何在Linux环境下启动、关闭以及强制终止Tomcat服务。 ...
在 Java 中,使用 Tomcat 服务器来发布 Web 应用程序是一种常见的做法。下面,我们将详细介绍如何使用 Java 代码来启动 Tomcat 服务器,并实现远程控制 Tomcat。 标题: Java 代码启动 Tomcat 描述: Java 实现 ...