今天遇到一个非常奇怪的问题,如标题所看到的:

linux下(之所以强调linux下,是由于在windows下正常),运行tomcat ./shutdown.sh 后,尽管tomcat服务不能正常訪问了,可是ps -ef | grep java 后,发现tomcat相应的java进程未随web容器关闭而销毁,进而存在僵尸java进程。

刚開始百思不得其解,google下,发现存在一种说法是:有非守护线程(即User Thread)存在,jvm不会退出(当JVM中全部的线程都是守护线程的时候,JVM就能够退出了;假设另一个或以上的非守护线程则JVM不会退出)。使用jstack工具进而确认是由于项目代码存在

scheduledExecutorService.scheduleAtFixedRate,众所周知,executorService会为之维护一个定时服务的线程池,该线程池并不会随着web容器关闭而销毁,只是有点让我非常费解,虽然我已经在代码中addShutdownHook(shutdown()) ,但实际证明,这个hook仅仅对Application.main时有效,在web容器中,hook会失效,所以并不会由于web容器关闭触发hook,进而能shutdown scheduledExecutorService。

(线程则是JVM级别的,假设你在Web 应用中启动一个线程,这个线程的生命周期并不会和Web应用程序保持同步。也就是说,即使你停止了Web应用,这个线程依然是活跃的。正是由于这个非常隐晦的问题,所以非常多有经验的开发人员不太赞成在Web应用中私自启动线程。



假设我们手工使用JDK Timer(Quartz的Scheduler),在Web容器启动时启动Timer,当Web容器关闭时,除非你手工关闭这个Timer,否则Timer中的任务还会继续执行!

Spring为JDK Timer和Quartz Scheduler所提供的TimerFactoryBean和SchedulerFactoryBean可以和Spring容器的生命周期关联,在 Spring容器启动时启动调度器,而在Spring容器关闭时,停止调度器。所以在Spring中通过这两个FactoryBean配置调度器,再从 Spring IoC中获取调度器引用进行任务调度将不会出现这样的Web容器关闭而任务依旧执行的问题。而假设你在程序中直接使用Timer或Scheduler,如不进行额外的处理,将会出现这一问题。

知道原因后,处理事实上非常easy,在ContextLoaderListener#contextDestroyed 容器关闭时主动销毁scheduledExecutorService:

    public void contextDestroyed(ServletContextEvent event)
{
//close ScheduledExecutorService in web container
AccessTokenScheduled.shutdownScheduledExecutor();
SystemTimer.shutdownScheduledExecutor();
super.contextDestroyed(event);
log.info("AppListener # context destroyed... ");
}

參考:http://blog.sina.com.cn/s/blog_613904cc0101i5em.html

http://m.blog.csdn.net/blog/lin910429/25716113

http://www.2cto.com/kf/201305/214127.html

linux下tomcat shutdown后 java进程依然存在的更多相关文章

  1. linux下Tomcat shutdown无效

    问题: linux下Tomcat shutdown无效 linux下关闭tomcat后,发现重新启动Tomcat后.port号提示被占用, 原因: 这时可能是项目中的后台线程或者socket依旧在执行 ...

  2. linux下Tomcat 安装后执行startup.sh,出现– Cannot find …bin/catalina.sh

    linux下Tomcat 安装后执行startup.sh,出现– Cannot find …bin/catalina.sh 是因为权限不够,执行以下命令就可以: chmod +x startup.sh ...

  3. linux下如何批量杀JAVA进程或某个进程方法

    linux下如何批量杀JAVA进程或某个进程方法 在工作中经常需要停止JAVA进程,停止时间也比较长,那么有时候因为一些情况,需要把 linux 下JAVA所有进程 kill 掉,又不能用killal ...

  4. (转)linux下如何批量杀JAVA进程或某个进程方法

    在工作中经常需要停止JAVA进程,停止时间也比较长,那么有时候因为一些情况,需要把 linux 下JAVA所有进程 kill 掉,又不能用killall 直接杀掉某一进程名称包含的所有运行中进程(我们 ...

  5. Linux下杀掉所有得java进程

    --转自https://blog.csdn.net/oppo62258801/article/details/81434038 1.Linux查看所有Java进程 ps -ef | grep java ...

  6. tomcat shutdown后,进程还存在linux系统中的解决办法

    基本原理为启动tomcat时记录启动tomcat的进程id(pid),关闭时强制杀死该进程 第一步 :vim修改tomcat下bin/catalina.sh文件,添加点东西,主要是记录tomcat的p ...

  7. linux下tomcat的shutdown命令杀不死进程

    tomcat在windows下可以直接关闭,但是貌似在Linux下有时候shutdown.sh 没有关闭tomcat进程:国庆前最后一天没事,解决你~~~~ 现象: 在Linux下shutdown.s ...

  8. 转 解决linux下tomcat的shutdown命令杀不死进程

    tomcat在windows下可以直接关闭,但是貌似在Linux下有时候shutdown.sh 没有关闭tomcat进程; 现象:在Linux下shutdown.sh ,然后查看tomcat进程发现没 ...

  9. Linux下tomcat的shutdown命令可以关闭服务但是杀不死进程

    Linux下tomcat的shutdown命令可以关闭服务但是杀不死进程 原因: 一般造成这种原因是因为项目中有非守护线程的存在: 解决方案: 一.从Tomcat上解决 方案1:(推荐的方案:因为一台 ...

随机推荐

  1. C++ ABI之名字改变,编译器生成符号研究(以Qt为例)

    在C++中,由于重载等技术的存在,编译器要将函数.结构体.类等等的信息传递给链接器,就不能像C语言那样简单地通过函数名来完成,它需要提供额外的参数信息,而还要和C语言共用链接器,这就需要用到名字改编( ...

  2. 使用SharedPreferences即时存储之后,不能即时获取到数据

    在这里简介一下我所遇到的情况,由于情况非常特殊,所以我就来记录一下自己在这个方面的经历! 事由:在我所做的app中有一个视频的播放功能,因为之前做优化的时候.我听说对于视频这种比較耗费资源的应该给他独 ...

  3. sharepoint 2013 附件控件FileUpload怎样检验是否为图片的方法

    记录一下关于附件控件FileUpload怎样检验是否为图片的方法: function checkImg() { var fileObj =document.getElementById('<%= ...

  4. spark sql 以JDBC为数据源

    一.环境准备: 安装mysql后,进入mysql命令行,创建测试表.数据: 将 mysql-connector-java 的jar文件拷贝到 \spark_home\lib\下,你可以使用最新版本,下 ...

  5. Palindromes _easy version

    Palindromes _easy version Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Jav ...

  6. ContentProvider中的数据库的生成时机以及ContentResolver的insert()方法总结

    经过几天的总结,以及结合一些代码的实际测试,终于算是明白了ContentProvider中的数据的生成时机了. 目录结构: MainActivity.java package com.wyl.cont ...

  7. ITextSharp 初次接触

    官网:http://www.itextpdf.com/  (英文好的建议看这里) 下面我就对itextsharp做一个初步的介绍,并把最近封装的一个用于生成pdf的类库提供给需要的朋友,对于大神你可以 ...

  8. codeigniter ,看完这些,就可以用它做项目了

    一.MVC 1,入口文件 唯一一个让浏览器直接请求的脚本文件 2,控制器 controller 负责协调模型和视图 3,模型 model 只负责提供数据,保存数据 4,视图 只负责显示,以及搜集用户的 ...

  9. 【转】介绍几个图论和复杂网络的程序库 —— BGL,QuickGraph,igraph和NetworkX

    原文来自:http://blog.sciencenet.cn/blog-404069-297233.html 作复杂网络研究离不开对各种实际或模拟网络的统计.计算.绘图等工作.对于一般性的工作,我们可 ...

  10. WPF中StringFormat 格式化 的用法

    原文 WPF中StringFormat 格式化 的用法 网格用法 <my:DataGridTextColumn x:Name="PerformedDate" Header=& ...