`

Web应用程序中线程的启动和关闭问题

 
阅读更多

我们知道静态变量是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

分享到:
评论

相关推荐

    tomcat启动和关闭

    Apache Tomcat是一个开源的Servlet容器,它实现了Java Servlet和JavaServer Pages(JSP)规范,是部署Java Web应用程序的常用工具。 首先,我们来看`shutdown.bat`文件。这个文件是Windows操作系统下的批处理脚本,...

    quartz单机和WEB应用

    在Web应用程序中集成Quartz,可以实现后台任务的自动化处理,比如数据同步、报表生成、邮件发送等。这篇博客“quartz单机和WEB应用”可能是探讨如何在单机环境下配置和使用Quartz,以及如何在Web应用中集成Quartz来...

    TongWeb常见问题处理

    Java应用程序,特别是Web应用,经常会在启动时开启线程、监听端口等服务。当应用被卸载时,如果没有在对应的`ServletContextListener`的`contextDestroyed`方法或Servlet的`destroy`方法中停止这些服务,就会导致...

    eclipse启动tomcat内存泄漏解决

    - 对于使用了外部库的应用程序,确保所有打开的资源都能正确关闭。 - 定期进行代码审查,查找可能导致内存泄漏的代码段,比如循环引用等。 4. **监控与诊断**: - 使用工具如VisualVM、JProfiler等监控Tomcat的...

    WEB服务器启动时加载一个ServerSocket服务

    这个类将在Web应用启动和关闭时分别调用`contextInitialized()`和`contextDestroyed()`方法。 ```java import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; public class ...

    c#多线程端口扫描程序源代码

    C#是一种广泛应用于桌面应用、游戏开发、Web应用和服务器端编程的面向对象的编程语言。在本项目中,"c#多线程端口扫描程序源代码" 提供了一个利用C#实现的网络工具,它能扫描指定目标主机的多个端口,以检测哪些端口...

    权威.NET多线程详解(源码示例)

    后台线程则不阻止应用程序关闭,即使有后台线程还在运行。 ### BeginXXX和EndXXX方法 这些方法用于异步编程,BeginXXX启动异步操作,EndXXX用于获取操作的结果。当操作完成后,可以通过EndXXX方法同步地等待结果。 ...

    多线程的运用e语言多线程 e多线程

    在E语言中,多线程能够帮助开发者在处理大量I/O操作、复杂的计算任务或者需要实时交互的应用场景时,提高程序的效率。通过创建多个线程,每个线程可以独立执行一段代码,而不影响其他线程的运行。 二、E语言中的...

    Java Web应用中常见的错误和异常问题处理.zip

    在Java Web应用开发中,错误和异常的处理是不可或缺的一部分,因为它们直接影响到程序的稳定性和用户体验。本文将深入探讨Java Web应用中遇到的一些常见错误和异常问题,并提供相应的处理策略。 1. **Servlet和JSP...

    JPEG图片浏览器(C#应用程序)

    “C#小应用程序”标签暗示这可能是一个轻量级的程序,专为快速启动和简单操作而设计。在C#中,可以利用Windows Forms或WPF(Windows Presentation Foundation)创建这样的应用。Windows Forms更适合快速开发,而WPF...

    基于ASP.net的多线程TCP端口扫描程序源码.zip

    ASP.NET是一种由微软开发的服务器端Web应用程序框架,主要用于构建动态网站、Web应用程序和服务。在这个“基于ASP.NET的多线程TCP端口扫描程序源码”项目中,开发者利用了ASP.NET的技术特性来实现了一个功能强大的...

    仿音速启动增强管理程序

    VB.NET是Microsoft .NET框架的一部分,提供了一种面向对象的编程环境,允许开发者创建桌面应用程序、Web应用程序和服务。VBEXE是Visual Basic .NET编译后的程序文件形式,通常包含完整的运行时环境,可以在没有安装...

    定时开关程序(c#)

    在IT行业中,编程语言C#是一种广泛用于开发桌面应用、Web应用、游戏和移动应用的强大工具。本项目“定时开关程序”是利用C#编写的一个实用程序,它能够按照预设的时间间隔执行启动或关闭指定程序的操作。对于那些...

    JAVA程序设计语言Applet应用程序.pdf

    ### JAVA程序设计语言Applet应用程序知识点详解 #### 1. Java程序分类 Java程序主要分为两类:Java Application 和 Java Applet。 - **Java Application**:这类程序是独立运行的Java程序,通常具备`main`方法作为...

    Windows 8系统中程序无响应且无法关闭.docx

    **XML Web Services** 是.NET Framework 中的一个重要概念,它允许不同系统之间的应用程序通过网络进行交互和共享数据。通过XML Web Services,不同平台的应用程序可以无缝地协同工作,即使它们使用的编程语言和操作...

    C#定时操作控制台应用程序

    在IT领域,C#是一种广泛使用的编程语言,尤其在开发Windows桌面应用、Web应用以及服务端应用程序时。本文将深入探讨如何使用C#构建一个定时操作的控制台应用程序,这在自动化任务执行、数据同步或者定期备份等场景中...

    c#中实现退出程序后自动重新启动程序的方法

    这个方法会结束当前应用程序线程,导致应用程序关闭。在大多数情况下,调用此方法会结束整个应用程序,除非有其他非UI线程仍在运行。 为了在退出程序后立即重新启动,我们可以创建一个新的线程并在退出之前启动它。...

    .net线程问答.net线程全攻略

    《.NET线程问答 .NET线程全...以上内容涵盖了.NET线程的基础知识,包括创建、使用和管理线程,以及在特定环境如WinForm和Web应用中的实践策略。理解并熟练运用这些知识,能帮助开发者编写出更加高效和健壮的并发程序。

    Linux下Tomcat的启动、关闭、杀死进程

    在Linux环境下部署和管理Java Web应用程序时,Apache Tomcat作为一款广泛使用的应用服务器,其操作过程对于系统管理员和开发人员来说至关重要。本文将详细介绍如何在Linux环境下启动、关闭以及强制终止Tomcat服务。 ...

    java代码启动tomcat

    在 Java 中,使用 Tomcat 服务器来发布 Web 应用程序是一种常见的做法。下面,我们将详细介绍如何使用 Java 代码来启动 Tomcat 服务器,并实现远程控制 Tomcat。 标题: Java 代码启动 Tomcat 描述: Java 实现 ...

Global site tag (gtag.js) - Google Analytics