tomcat shudown.sh 无法关闭

Tomcat使用shutdown.sh无法关闭Java进程的问题跟踪

问题:

在服务器上执行/usr/local/apache-tomcat-7.0.47-3100/bin/shutdown.sh后,使用

ps –aux|grep java 命令查看,发现java进程还存在,但是服务已经不可用了,即服务没有完全关闭。

 

跟踪过程:

1、  百度查找“Tomcat无法 shutdown进程”,得出原因为:有非守护线程存在的时候,JVM是不会退出的。

2、  查找shutdown.sh执行之后,有哪些非守护线程存在:

  操作:1)执行shutdown.sh

        2)使用jdk自带的jstack工具导出java进程中的线程堆栈:

             使用ps –aux|grep java查看java进程pid(pid为一个整数);

             使用jstack pid >/usr/local/threaddump.txt   (该命令将所有线程堆栈导出到/usr/local/threaddump.txt文件中)。

3、  分析/usr/local/threaddump.txt中的线程堆栈,找到非守护线程,jvm的GC线程不用看。

可以使用UltraEidt编辑器辅助查找,搜索“prio=”,列出所有的线程,可以很容易的看到daemon字样的是守护线程,没有daemon字样的是非守护线程。

 

4、  本次跟踪的threaddump.txt只找到一个非守护线程的堆栈,如下:

"pool-2-thread-1" prio=10 tid=0x00007f26244af000 nid=0xcb2 waiting on condition [0x00007f2616515000]

 

   java.lang.Thread.State: TIMED_WAITING (parking)

at sun.misc.Unsafe.park(Native Method)

- parking to wait for  <0x00000000c2aedf98> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)

at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:196)

at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2025)

at java.util.concurrent.DelayQueue.take(DelayQueue.java:164)

at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:609)

at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:602)

at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:947)

at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:907)

at java.lang.Thread.run(Thread.java:662)

5、  查找与该线程堆栈有关业务代码,经查,对应的代码为:

 //启动就运行,之后每12小时调用一次(默认)

       final int time = SystemInit.getSynLmpTime();

       Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable() {

            @Override

            public void run() {

                 executeSynBrandData();

                 executeSynCategoryData();

                 executeSynStoreData();

                 executeDeleteByBeforeDays(SystemInit.getDeleteBeforeDays());

            }

       }, 0, time, TimeUnit.HOURS);

修改方法:

外层代码要持有线程池的引用,以便shutdown时可以调用scheduledExecutorService.shutdown();进行关闭。

ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1);

scheduledExecutorService.scheduleAtFixedRate(new Runnable() {

            @Override

            public void run() {

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值