Tomcat 关闭时报错

最近tomcat走普通的关闭方式无法正常关闭,会报一些Error,用的是Tomcat7,据说是Tomcat7在关闭的时候加了一些检查线程泄漏内存泄露的东西

总结起来,在我项目中有这么几个原因会导致关闭不了:

1、使用了@Scheduled注解

最后查出来原因是因为在bean里面使用了  @Scheduled    注解,而Tomcat关闭的时候,spring并不能主动关闭这些Schedule,也就是说这注解有缺陷,慎用。

替代方法就是放弃spring的Scheduled注解方式使用quartz,这里我把所有的spring注解计划任务换回了配置文件:

<bean id="syncProgramQuartz" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
        <property name="targetObject" ref="taskProgramSync">
        </property>
        <property name="targetMethod" value="sync">
        </property>
        <property name="concurrent" value="false">
        </property>
    </bean>

    <bean id="syncProgramQuartzTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
        <property name="jobDetail" ref="syncProgramQuartz"></property>
        <property name="cronExpression">
            <value>${SYN_PROGRAM_TASK_CRON}</value>
        </property>
    </bean>
    
    

    <bean name="startQuertz" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
        <property name="triggers">
            <list>
                <ref bean="syncProgramQuartzTrigger" />
            </list>
        </property>
    </bean>

这样就不报 pool-xxxx-1无法关闭之类的错误了。

2、连接池没有手动关闭


这个也是在自定义的Listener里面处理,代码如下

new Thread() {
            public void run() {
                Enumeration<Driver> drivers = DriverManager.getDrivers();  
                while (drivers.hasMoreElements()) {  
                    Driver driver = drivers.nextElement();  
                    try {  
                        DriverManager.deregisterDriver(driver);  
                    } catch (SQLException e) {  
                        e.printStackTrace();  
                    }  
                }  
            }
        }.start();

3、AbandonedConnectionCleanupThread单独关闭,这个在关完连接池后就顺便一起关了吧

try {
            AbandonedConnectionCleanupThread.shutdown();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

一般做完以上三步就差不多了。 

4、个别线程强行阻碍

对于这种管不了的线程我们就根据其线程名将其关闭

Set<Thread> threads = Thread.getAllStackTraces().keySet();      
          for (Thread thread : threads) {                  
              if(thread.getName().equals("xxxxxxthread")){    
                  try {      
                      thread.interrupt();
                      System.out.println(thread.getName()+" is stopped");
                        return;    
                   } catch (Exception e) {  
                       System.out.println(thread.getName()+" stop error");
                       e.printStackTrace();
                   }      
            }      
          } 
原文地址:https://www.cnblogs.com/flying607/p/7486036.html