当前位置: 首页 > Java Core > 正文

Java项目中Timer应用问题分析一例

目 录
 [ 隐藏 ]

1.背景 

项目中使用Timer来设置一个定时任务,在每天凌晨2点生成一个报告。项目是使用tomcat的一个Web程序。 
web程序在tomcat启动时在初始化 servlet时 设置Timer的schedule。 

2.问题现象 

Timer关联的TimerTask最近有个改动,需要更新代码。代码更新以后,部署web程序,重启tomcat后发现 
似乎有两个Timer再跑:修改前的TimerTask代码依然在运行,修改后的代码也在运行。 

3.问题分析 

项目中 构造 Timer 初始化代码为: Timer task = new Timer(); 
查询API后发现, Timer的构造函数有以下几种: 

Timer() 
Creates a new timer. 
Timer(boolean isDaemon) 
Creates a new timer whose associated thread may be specified to run as a daemon. 
Timer(String name) 
Creates a new timer whose associated thread has the specified name. 
Timer(String name, boolean isDaemon) 
Creates a new timer whose associated thread has the specified name, and may be specified to run as a daemon. 

默认的构造函数: Creates a new timer. The associated thread does not run as a daemon. 
表示用来 执行TimerTask的线程是非daemon线程。  我们知道,JVM中如果所有正在运行的线程都是daemon线程,那么JVM将自动退出,即不再继续运行了。 

这里,因为是用 new Timer() 构造的 Timer,导致关联的线程是非daemon线程。 于是,在stop tomcat的时候,这个Timer关联的线程还是在继续运行的。 
因此,有新旧两个版本的 TimerTask在同时运行。 

4.问题分析的验证 

1) 使用 ps -ef | grep tomcat 检查 有多少个 tomcat线程 
2) 重启tomcat 
3) 再次 运行 ps -ef | grep tomcat 发现 果然又多了一个 tomcat线程 

5.解决问题 

使用 下面的构造函数生成 Timer实例 
Timer(String name, boolean isDaemon) 
Creates a new timer whose associated thread has the specified name, and may be specified to run as a daemon. 

Timer task = new Timer(“My Timer Task”,true) 

表示给执行TimerTask的线程起了个名字My Timer Task,这样方便实用 jstack工具时快速的定位到这个线程。 
同时,将isDaemon 设置为true,这样在tomcat stop的时候,与之相关的JVM会自动退出,因此所有daemon线程也就不会再运行了。 
也就不会出现几个tomcat线程同时运行的情况(其实是执行Tomcat的JVM没有退出,因为还有TimerTask的线程在跑着)。 

6. 结论 

当构造函数有多个的时候,尽量先搞清楚各个构造函数的区别,以及为什么要有这些不同的构造函数,然后再选择一个合适的构造函数来初始化。 
可以使用ScheduledThreadExecutor 来替代Timer。

赞 赏

   微信赞赏  支付宝赞赏


本文固定链接: https://www.jack-yin.com/coding/java-core/2680.html | 边城网事

该日志由 边城网事 于2016年04月11日发表在 Java Core 分类下, 你可以发表评论,并在保留原文地址及作者的情况下引用到你的网站或博客。
原创文章转载请注明: Java项目中Timer应用问题分析一例 | 边城网事

Java项目中Timer应用问题分析一例 暂无评论

发表评论

快捷键:Ctrl+Enter