`

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容器中的ThreadLocal容易产生的问题

    运行在tomcat容器中的ThreadLocal容易产生的问题ThreadLocal在tomcat容器中的的生命周期并不等于web request的生命周期,所以(以下讨论的是tomcat容器中使用ThreadLocal),所以ThreadLocal不应保存与请求会影响的...

    IIS6.0 IIS,互联网信息服务

    在这里可以管理的范围主要包括对Web站点和FTP站点进行的新建、修改、启动、停止和删除等操作。 [编辑本段]有关IIS的常见问题解答  四、本部分常见问题解答 Q:在上文中所涉及到的网址中,有的加了“http://”,有的...

    API之网络函数---整理网络函数及功能

    PostThreadMessage 将一条消息投递给应用程序 RegisterWindowMessage 获取分配给一个字串标识符的消息编号 ReplyMessage 答复一个消息 SendMessage 调用一个窗口的窗口函数,将一条消息发给那个窗口 ...

    Android程序设计基础

    浏览器和地图视图可以直接嵌入在应用程序中。所有这些内置服务有助于提高功能的标准,同时降低开发成本。  应用程序生命周期的自动化管理。多层安全措施将程序彼此分离,这将使智能电话的系统稳定性达到前所未有的...

    Visual.Basic.2010.&.NET4.高级编程(第6版)-文字版.pdf

    13.1.3 合并网络和应用程序开发 510 13.1.4 web服务基础 511 13.1.5 存在的问题 512 13.1.6 其他技术 512 13.1.7 web服务 513 13.1.8 组合起来 514 13.1.9 wcf服务的构成 514 13.2 向soa迈出一大步 ...

    Visual C++ 程序开发范例宝典 源码 光盘 part2

    SQLcServer数据库进行录入和存储Word文档 8.10 数据备份恢复 cc实例228 Access数据库备份与还原 cc实例229 SQLcServer数据库备份与恢复 cc实例230 定时数据备份 8.11 其他数据库技术 实例231 断开...

    网络编程实用教程(第三版).zip

    9.2.3 创建一个Web浏览器型的应用程序的一般步骤 256 9.3 Web浏览器应用程序实例 261 9.3.1 程序实现的目标 261 9.3.2 创建实例程序 262 习题 265 实验 265 第 10章 电子邮件协议与编程 267 10.1 电子...

    Visual C++程序开发范例宝典(PDF扫描版).part2

     实例231 断开SQLcServer数据库与其他应用程序的连接   cc实例232 在VisualcC++中执行事务   cc实例233 在程序中执行SQL脚本   cc实例234 利用SQL语句执行外围命令  第9章 SQL查询相关技术   9.1 ...

    C#实训教程

    15.3 应用程序的启动和关闭 308 15.4 内容总结 308 16 高级用户界面 309 16.1 打印控件的使用 309 16.2 PrintDocument组件 309 16.3 PrintPreviewControl组件 310 16.4 PrintDialog 组件 310 16.5 ...

    Visual C++程序开发范例宝典(PDF扫描版).part3

     实例231 断开SQLcServer数据库与其他应用程序的连接   cc实例232 在VisualcC++中执行事务   cc实例233 在程序中执行SQL脚本   cc实例234 利用SQL语句执行外围命令  第9章 SQL查询相关技术   9.1 ...

    vc++ 应用源码包_1

    在MFC应用程序中浏览PDF、Word文档文件 vcdialog 自绘对话框。 vc编程:自动停靠窗体,吸附窗体 OnMoving事件处理。 vc基于HTTP协议断点续传和多线程下载源代码 VC满屏开满玫瑰花 VC然输入框出现气球提示 调用...

    Visual C++程序开发范例宝典(光盘) 第四部分

    实例231 断开SQL Server数据库与其他应用程序的连接 实例232 在Visual C++中执行事务 实例233 在程序中执行SQL脚本 实例234 利用SQL语句执行外围命令 第9章 SQL查询相关技术 9.1 通用查询 实例235 SQL语句的...

    Visual C++程序开发范例宝典(光盘) 第八部分

    实例231 断开SQL Server数据库与其他应用程序的连接 实例232 在Visual C++中执行事务 实例233 在程序中执行SQL脚本 实例234 利用SQL语句执行外围命令 第9章 SQL查询相关技术 9.1 通用查询 实例235 SQL语句的...

    超级有影响力霸气的Java面试题大全文档

    多态性语言具有灵活、抽象、行为共享、代码共享的优势,很好的解决了应用程序函数同名问题。 5、String是最基本的数据类型吗?  基本数据类型包括byte、int、char、long、float、double、boolean和short。  java....

    C#源码大集合 02(共3卷)

    │ └─第8章 Web应用 │ ├─实例136 如何在Web页中使用广告控件 │ ├─实例137 如何在Web页中使用表格控件 │ ├─实例138 如何在Web页中使用日历控件 │ ├─实例139 如何在Web页中使用数据网格控件 │ ├─实例...

    Spring3.x企业应用开发实战(完整版) part1

    13.6.4 Web应用程序中调度器的启动和关闭问题 13.7 小结 第14章 使用OXM进行对象XML映射 14.1 认识XML解析技术 14.1.1 什么是XML 14.1.2 XML的处理技术 14.2 XML处理利器:XStream 14.2.1 XStream概述 14.2.2 快速...

    《Visual C# .NET精彩编程实例集锦》配套光盘文件【全】

    第8章 web应用 实例136 如何在web页中使用广告控件 实例137 如何在web页中使用表格控件 实例138 如何在web页中使用日历控件 实例139 如何在web页中使用数据网格控件 实例140 如何在web页中使用比较校验控件 ...

    Spring.3.x企业应用开发实战(完整版).part2

    13.6.4 Web应用程序中调度器的启动和关闭问题 13.7 小结 第14章 使用OXM进行对象XML映射 14.1 认识XML解析技术 14.1.1 什么是XML 14.1.2 XML的处理技术 14.2 XML处理利器:XStream 14.2.1 XStream概述 14.2.2 快速...

    C#源码大集合 01(共3卷)

    │ └─实例135 如何扫描端口 │ └─第8章 Web应用 │ ├─实例136 如何在Web页中使用广告控件 │ ├─实例137 如何在Web页中使用表格控件 │ ├─实例138 如何在Web页中使用日历控件 │ ├─实例...

Global site tag (gtag.js) - Google Analytics