我在 Spring 3.2.4 Web 应用程序中有一个计划任务,计划以 1 分钟的固定速率运行。大约一天后,任务停止执行,但无法预测它何时发生,因此我未能在我的开发环境中重现此情况。
在这恰好有线索停止的线索之后,我尝试收集线程转储,但是,如果我正确解释了线程转储,则线程不会在我的代码中被阻止。
线程转储的输出示例如下所示(线程池中的每个线程都有一个类似的转储):
Thread 5510: (state = BLOCKED)
- sun.misc.Unsafe.park(boolean, long) @bci=0 (Compiled frame; information may be imprecise)
- java.util.concurrent.locks.LockSupport.parkNanos(java.lang.Object, long) @bci=20, line=196 (Compiled frame)
- java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(long) @bci=68, line=2025 (Compiled frame)
- java.util.concurrent.DelayQueue.take() @bci=57, line=164 (Compiled frame)
- java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take() @bci=4, line=609 (Interpreted frame)
- java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take() @bci=1, line=602 (Interpreted frame)
- java.util.concurrent.ThreadPoolExecutor.getTask() @bci=78, line=947 (Compiled frame)
- java.util.concurrent.ThreadPoolExecutor$Worker.run() @bci=18, line=907 (Compiled frame)
- java.lang.Thread.run() @bci=11, line=662 (Interpreted frame)
对我来说,这看起来很正常 - 线程在池中等待。
我的问题是如何进一步调试?有没有办法以某种方式在运行时访问和转储有关 Spring 调度状态的信息(例如下一次执行时间、上次执行时间、正在执行哪些作业、线程池中有多少空闲线程等)?
最佳答案
问题发生后,再次进行线程转储后,我发现了原因 - 计划任务存在无限循环,在某些情况下可能会发生。
供将来引用,线程转储是通过以下方式获取的:
jstack [process id] > threaddump.txt
我设法解决了这个问题,但我仍然不太明白为什么有问题的无限循环没有出现在问题发生几个小时后的线程转储中。
关于java - 使用fixedRate调度的Spring 3似乎在某个点后意外停止执行,如何调试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21675483/