web应用关闭后线程不回收问题

  今天看《spring3.0企业应用开发实战》中关于web应用程序中调度器的启动和关闭问题中有这样一段话:

  静态变量是ClassLoader级别的,如果web应用程序停止,这些静态变量也会从jvm中清除。但是线程则是JVM级别的,如果用户在web应用中启动一个线程,这个线程的生命周期并不会和web应用程序保持同步。也就是说,即使停止了web应用,这个线程也依旧是活跃的。

  因此为了真正的验证上面的结论,实战了一下书中的例子

一 配置tomcat应用管理页面

1.首先启动tomcat后,通过web端访问http://localhost:8080/,出现下面页面

2.点击Manager App打开输入用户名密码弹出窗口

3.因不知道用户名密码,直接取消掉,出现错误信息提示新页面

4.从上面的新页面中可以看出来,意思是如果没有改动配置文件的情况下,直接打开conf目录下的tomcat-users.xml文件,通过添加角色到用户上面可以访问对应的权限页面

  • manager-gui:访问html页面,(即URL路径为/manager/html/*),有访问status权限
  • manager-script:访问纯文本,(即URL路径为/manager/text/*),有访问status权限
  • manager-jmx:访问JMX代理,(即URL路径为/manager/jmxproxy/*),有访问status权限
  • manager-status:查看应用状态。

5.从tomcat的帮助文档中也可以找到相关信息,http://localhost:8080/docs/manager-howto.html中,

6.因此直接在tomcat用户的角色上添加manager-gui就可以访问页面了

7.重启tomcat,用户名tomcat,密码tomcat登录,就可以查看应用管理相关页面了。

 

二 代码验证

1.新建web应用程序,并新建TimerListenerTest类,实现ServletContextListener,代码如下

 1 package com.test.timer;
 2 
 3 import java.util.Date;
 4 import java.util.Timer;
 5 import java.util.TimerTask;
 6 
 7 import javax.servlet.ServletContextEvent;
 8 import javax.servlet.ServletContextListener;
 9 
10 public class TimerListenerTest implements ServletContextListener {
11 
12     private Timer timer;
13 
14     @Override
15     public void contextDestroyed(ServletContextEvent arg0) {
16         System.out.println("---应用关闭---");
17     }
18 
19     @Override
20     public void contextInitialized(ServletContextEvent arg0) {
21         System.out.println("---应用开启---");
22 
23         timer = new Timer();
24 
25         TimerTaskTest task = new TimerTaskTest();
26 
27         timer.schedule(task, 1000L, 1000L);
28     }
29 
30     class TimerTaskTest extends TimerTask {
31 
32         @Override
33         public void run() {
34             System.out.println("-----" + new Date());
35         }
36     }
37 
38 }

2.部署应用,并启动tomcat,程序运行如下

-----Sat Jan 02 22:42:59 CST 2016
-----Sat Jan 02 22:43:00 CST 2016
-----Sat Jan 02 22:43:01 CST 2016
-----Sat Jan 02 22:43:02 CST 2016

3.通过tomcat web管理页面直接停止应用,下图中的WebTest

4.观察后台运行,出现

 

5.从上面可以看出,web应用的确运行了contextDestroyed方法来进行相关的销毁操作,但是观察应用运行状态,

应用程序中的线程还是running

6.当然该处程序可以通过timer.cannel()方法来收工回收关闭定时器来关闭线程

7.github代码地址https://github.com/lixiaojiao2010/WebTest

  由此可以验证文章开始的时候的结论的正确性。

 

posted @ 2016-01-02 22:59  CoderToSurvive  阅读(3497)  评论(0编辑  收藏  举报