有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

javatomcat:等待条件线程

我正在调查tomcat关机过程中的一个奇怪问题:runnig关机后。sh java进程仍然出现(我使用ps -ef|grep tomcat检查它) 情况有点复杂,因为我对服务器的访问非常有限(例如,没有调试)

我采用了线程转储(通过使用kill -3 <PID>)和堆转储(通过使用远程jConsole和热点功能)

在查看线程转储后,我发现:

"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是用来做什么的

谢谢


共 (1) 个答案

  1. # 1 楼答案

    经过一番挣扎之后,我发现,冰冷的线总是同名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");
        }
    }
    

    之后问题就解决了