2017-07-19 103 views
2

我正在調查與tomcat關機過程有關的奇怪問題:在runnig shutdown.sh之後,java進程仍然出現(我通過使用ps -ef|grep tomcat來檢查它) 這種情況有點複雜,因爲我有對服務器的訪問非常有限(例如,沒有調試)tomcat:等待條件線程

我使用遠程jConsole和熱點功能執行了線程轉儲(使用kill -3 <PID>)和堆轉儲。

尋找到線程轉儲後,我發現這一點:

"pool-2-thread-1" #74 prio=5 os_prio=0 tid=0x00007f3354359800 nid=0x7b46 waiting on condition [0x00007f333e55d000] 
    java.lang.Thread.State: WAITING (parking) 
     at sun.misc.Unsafe.park(Native Method) 
     - parking to wait for <0x00000000c378d330> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) 
     at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175) 
     at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039) 
     at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1081) 
     at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809) 
     at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067) 
     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127) 
     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
     at java.lang.Thread.run(Thread.java:748) 

所以,我對這個問題的理解是如下:有是在CachedThreadpool使用的資源(DB連接或別的東西),而這個資源現在被鎖定, 並阻止線程pool-2-thread-1停止。假設這個線程不是deamon - JVM不能正常停止。

有沒有辦法找出哪些資源被鎖定,鎖定在哪裏以及如何避免這種情況?另一個問題是 - 如何防止這種情況? 另一個是:地址0x00007f333e55d000的用途是什麼?

謝謝!

回答

0

經過一番苦苦掙扎之後,我發現凍線總是有相同的名字pool-2-thread-1。我grep項目的所有來源找到任何預定線程池啓動的任何地方:Executors#newScheduledThreadPool。經過大量時間後,我記錄了所有這些地方,線程池中有線程名稱。 再一次重啓服務器和陷阱!

我發現了一個線程池,即開始只有一個線程和使用下面的代碼:

private void shutdownThreadpool(int tries) { 
    try { 
     boolean terminated; 
     LOGGER.debug("Trying to shutdown thread pool in {} tries", tries); 
     pool.shutdown(); 
     do { 
      terminated = pool.awaitTermination(WAIT_ON_SHUTDOWN,TimeUnit.MILLISECONDS); 
      if (--tries == 0 
        && !terminated) { 
       LOGGER.debug("After 10 attempts couldn't shutdown thread pool, force shutdown"); 
       pool.shutdownNow(); 
       terminated = pool.awaitTermination(WAIT_ON_SHUTDOWN, TimeUnit.MILLISECONDS); 
       if (!terminated) { 
        LOGGER.debug("Cannot stop thread pool even with force"); 
        LOGGER.trace("Some of the workers doesn't react to Interruption event properly"); 
        terminated = true; 
       } 
      } else { 
       LOGGER.info("After {} attempts doesn't stop", tries); 
      } 
     } while (!terminated); 
     LOGGER.debug("Successfully stop thread pool"); 
    } catch (final InterruptedException ie) { 
     LOGGER.warn("Thread pool shutdown interrupted"); 
    } 
} 

之後,這個問題得到了解決。