解決linux下tomcat停止進(jìn)程任存在問題
在Linux下(之所以強(qiáng)調(diào)linux下房官,是因?yàn)樵趙indows下正常),執(zhí)行tomcat ./shutdown.sh 后朽缎,雖然tomcat服務(wù)不能正常訪問惨远,但是ps -ef |grep tomcat 后,發(fā)現(xiàn)tomcat對(duì)應(yīng)的java進(jìn)程未隨web容器關(guān)閉而銷毀话肖,進(jìn)而存在僵尸java進(jìn)程北秽。多次shutdown以后會(huì)發(fā)現(xiàn)系統(tǒng)內(nèi)存溢出,然后需要一個(gè)一個(gè)把tomcat的進(jìn)程殺掉
問題原因
在Linux系統(tǒng)中當(dāng)有非守護(hù)線程(即User Thread)存在最筒,jvm不會(huì)退出(當(dāng)JVM中所有的線程都是守護(hù)線程的時(shí)候贺氓,JVM就可以退出了;如果還有一個(gè)或以上的非守護(hù)線程則JVM不會(huì)退出)床蜘。
在本人項(xiàng)目中是因?yàn)槭褂昧?strong>ScheduledExecutorService建立了一個(gè)定時(shí)任務(wù)辙培,(executorService會(huì)為之維護(hù)一個(gè)定時(shí)服務(wù)的線程池,在web容器中建立的線程的生命周期并不會(huì)和Web應(yīng)用程序保持同步悄泥,該線程池并不會(huì)隨著web容器關(guān)閉而銷毀)虏冻,因此在tomcat停止的時(shí)候沒有將這個(gè)定時(shí)任務(wù)線程不會(huì)停止肤粱。
問題解決
ScheduledExecutorService有一個(gè)shutdownNow()方法弹囚,只需要在系統(tǒng)停止時(shí)調(diào)用這個(gè)方法將定時(shí)任務(wù)停掉即可。
另外:
Spring為JDK Timer和Quartz Scheduler所提供的TimerFactoryBean和SchedulerFactoryBean能夠和Spring容器的生命周期關(guān)聯(lián)领曼,在 Spring容器啟動(dòng)時(shí)啟動(dòng)調(diào)度器鸥鹉,而在Spring容器關(guān)閉時(shí),停止調(diào)度器庶骄。所以在Spring中通過這兩個(gè)FactoryBean配置調(diào)度器毁渗,再從 Spring IoC中獲取調(diào)度器引用進(jìn)行任務(wù)調(diào)度將不會(huì)出現(xiàn)這種Web容器關(guān)閉而任務(wù)依然運(yùn)行的問題。