我在用Tomcat的时候遇到了一个问题,写了一个线程的类,用于扫描数据库的变动,然后写了一个Servlet类,在Web.xml里配置好,使得线程在Web引擎启动时就生效.在servlet里里写好了init和destory,如下
==============================
    public void init() throws ServletException {
         DBThread dbThread = new DBThread();
         dbThread.start();
    }
    public void destroy() {
        dbThread.interrupt();
        
    }
==============================但是在我关闭Tomcat的时候,线程并未结束,反而因为获取不到相应的资源(比如数据库连接),而频繁抛出错误.我的问题是:
1. Web引擎可以自动关闭线程吗?
2. servlet里的destroy什么时候调用的?是Web引擎自己调用的吗?
3. 我现在的线程关闭不了,应该怎么办?

解决方案 »

  1.   

    通过日志查到了servlet里的destroy方法运行了,可是相应的线程仍然在运行
      

  2.   

    您这个程序是和web一起运行的嘛,如果是那就要看看您的start里面怎么写的了,如果是和web启动运行,web停止了,它也会停止啊
      

  3.   

    继承 ServletContextListener 实现public void contextInitialized(ServletContextEvent event) 和 public void contextDestroyed(ServletContextEvent event)
    方法就可以,
    我在tomcat下就是这么做的,在contextInitialized中加载我的定时器以及相关的资源,在contextDestroyed 关闭相关资源就行了
      

  4.   

        public void init() throws ServletException { 
            DBThread dbThread = new DBThread(); 
            dbThread.start(); 
        } 
        public void destroy() { 
            dbThread.interrupt(); 
            
        } 如果代码真的是这样写的,那是真的有问题!因为你在init中start的和在destory中interrupt的根本就不是同一个
    init() 里面是一个局部变量执行的线程,线程对象run运行完了就被gc了。
    而destroy()里面interrupt的应该是类的成员变量,跟init里面的完全不是一回事
      

  5.   

    ...
    2. servlet里的destroy什么时候调用的?是Web引擎自己调用的吗? 
       destroy()方法标志servlet生命周期的结束。当服务需要关闭时,它调用servlet的destroy()方法。一般调用servlet容器的事例调用destroy()方法.
    3. 我现在的线程关闭不了,应该怎么办?
       一般线程正常执行完毕,正常结束。
    LZ,应该再看看你的程序,是不是写的有问题.
      

  6.   

    不是这样写的,呵呵,变量的定义是在init()方法体外面的.
    我在Thread类里写的方法就是创建数据库连接,查询,关闭数据库连接.
    结果shutdown Web引擎后,这个类里关于数据库的操作还在不停的操作,当然这些操作获取不到相应的资源,然后就不停的抛出错误了........
      

  7.   

    interrupt只中断处于sleep,wait,join状态的线程,正常的情况下他是终端不了的,网上最流行的中断线程的方法是通过一个共享变量来中断,比如:
    private boolean flag = true;
    public void run() {
    while (getFlag()) {
    //操作
    }
    }
    public synchronized void setFlag(boolean flag) {
    this.flag = flag;
    } public synchronized boolean getFlag() {
    return flag;
    }
    通过修改flag变量为false来停止线程,楼主可以把setFlag(false)放到destroy方法中
      

  8.   

    1.不会自动关闭
    2.当servlet被卸载后,jvm回收内存时才调用;不是web引擎自己调用的
    3.关闭tomcat或自己写用来关闭特定线程的方法来实现
      

  9.   

    明白你的意思了:
    在开TOMCAT的时候,你启动了一个定时任务
    而你关闭TOMCAT的时候,可能这个定时任务正在执行,关闭TOMCAT导致这个任务无法正常执行而出错。对吧?的确是这样的,TOMCAT关闭是强制性的,不会管还有没有线程正在运行。
      

  10.   

    可以写一个实现ServletContextListener的监听器,在contextDestroyed方法中写关闭动作。
    contextDestroyed在TOMCAT停止时候运行。
      

  11.   

    正解!由于tomcat在关闭的时候会自动调用servlet的destroy方法,所以你可以在该方法中实行关闭线程的操作