我做了一个观察,我想完全理解它。
首先,我定期进行线程转储并创建线程状态的摘要:
jstack -l 19498 > dump.txt ; awk '/State: / { print }' < dump.txt | sort | uniq -c
上面命令的结果如下所示:
70 java.lang.Thread.State: RUNNABLE
8 java.lang.Thread.State: TIMED_WAITING (on object monitor)
1 java.lang.Thread.State: TIMED_WAITING (sleeping)
171 java.lang.Thread.State: WAITING (on object monitor)
RUNNABLE
= 实际处理 Web 应用程序的请求
TIMED_WAITING
= Quartz Scheduler 线程
WAITING
= 等待处理即将到来的 HTTP 请求的空闲线程
WAITING 线程示例(所有 WAITING 看起来像这样):
"http-80-178" daemon prio=10 tid=0x00007fa8c0bbe000 nid=0x2e11 in Object.wait() [0x00007fa8aaae9000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x00007fa8e6b873c8> (a org.apache.tomcat.util.net.JIoEndpoint$Worker)
at java.lang.Object.wait(Object.java:485)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.await(JIoEndpoint.java:458)
- locked <0x00007fa8e6b873c8> (a org.apache.tomcat.util.net.JIoEndpoint$Worker)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:484)
at java.lang.Thread.run(Thread.java:619)
Locked ownable synchronizers:
- None
Tomcat 配置
我的 Tomcat 配置参数使用的是默认值,意思是
minSpareThreads = 25
(因此 Tomcat 确保有 25 个线程准备好处理
maxThreads = 200
(200 个请求可以在没有警告的情况下并行处理)
acceptCount = 100
(如果所有 200 个线程都忙,HTTP 连接器可以排队额外的 100 个请求)
问题
当我定期执行命令时,我看到线程总数正在增加。没有BLOCKING
线程。
我不明白为什么线程数在增加,因为WAITING
状态中有很多很多线程,准备处理另一个 HTTP 请求。
我还看到RUNNABLE
+WAITING
在一段时间内(例如 1 小时)是恒定的,但随后它增加了 5 或 6 并再次保持不变。似乎线程池越来越大,直到达到限制,Tomcat关闭......
这些TIMED_WAITING
线程很可能来自运行在同一个 JVM 中的 Quartz 调度程序。
我对值的解释不正确吗?