TOMCAT下shutdown不能完全关闭的解决方法


经常碰到shutdown之后不能完全关闭, 每次kill -9 操作麻烦且破换程序处理, 借鉴网上资料作下整理:

1. ps -aux | grep 8089/bin 找到遗留的进程PID


2. 使用jdk自带的jstack pid 查看具体线程


3. ServletContextListener服务监听器的销毁方法中, 增加关闭线程的处理:

public class SystemContextListener implements ServletContextListener
{

	private static Logger logger = Logger.getLogger(SystemContextListener.class);
	
	// 需要强制关闭的线程名
	public static final List<String> MANUAL_DESTROY_THREAD_IDENTIFIERS = Arrays.asList("QuartzScheduler", "scheduler_Worker", "miiapQuartzFactory_QuartzSchedulerThread", "MultiThreadedHttpConnectionManager cleanup");  
	
	@Override
	public void contextDestroyed(ServletContextEvent contextEvent) {

		// 关闭T2接口服务
		T2Interface.stop();

		destroyJDBCDrivers();
		destroySpecifyThreads();

		
	}

	@Override
	public void contextInitialized(ServletContextEvent contextEvent)
	{

		try
		{
			
			// 初始化spring容器
			SpringBeanFactory.init("classpath*:application*.xml");
			
			// 初始化, 读取系统配置
			ConfigProperties.initALL();
			
			
			// 启动T2接口服务
			T2Interface.initConfigs();
			T2Interface.start();
			


		}
		catch (Exception e)
		{
			e.printStackTrace();
			logger.error(e.getMessage(), e);
		}

	}
	
	/**
	 * 注销线程
	 */
	private void destroySpecifyThreads() {  
        final Set<Thread> threads = Thread.getAllStackTraces().keySet();  
        for (Thread thread : threads) {  
        	// 默认会把所有调度相关的线程关闭
            if (needManualDestroy(thread) || (thread.getName()!= null && thread.getName().toUpperCase().indexOf("QUARTZ")!= -1)) {  
                synchronized (this) {  
                    try {  
                        thread.stop();  
                        logger.debug(String.format("Destroy  %s successful", thread));  
                    } catch (Exception e) {  
                        logger.warn(String.format("Destroy %s error", thread), e);  
                    }  
                }  
            }  
        }  
    }  
  
	/**
	 * 需要销毁的线程名
	 * @param thread
	 * @return
	 */
    private boolean needManualDestroy(Thread thread) {  
        final String threadName = thread.getName();  
        for (String manualDestroyThreadIdentifier : MANUAL_DESTROY_THREAD_IDENTIFIERS) {  
            if (threadName.contains(manualDestroyThreadIdentifier)) {  
                return true;  
            }  
        }  
        return false;  
    }  
  
    /**
     * 注销JDBC驱动
     */
    private void destroyJDBCDrivers() {  
        final Enumeration<Driver> drivers = DriverManager.getDrivers();  
        Driver driver;  
        while (drivers.hasMoreElements()) {  
            driver = drivers.nextElement();  
            try {  
                DriverManager.deregisterDriver(driver);  
                logger.debug(String.format("Deregister JDBC driver %s successful", driver));  
            } catch (SQLException e) {  
                logger.warn(String.format("Deregister JDBC driver %s error", driver), e);  
            }  
        }  
    }  


}




评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

麦神-mirson

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值